帝国CMS多值字段morevaluefield解密

澳门新葡亰手机版 23

帝国CMS多值字段morevaluevield解密,深度解析帝国CMS多值字段技巧秘诀。

  • awk介绍
  • awk变量
  • printf命令:实现格式化输出
  • 操作符
  • awk pattern
  • awk action
  • awk数组
  • awk函数
  • awk脚本

基本概述

一、awk介绍

  • 功能:
    报告生成器,模式化文本输出
    同时也是一门语言:模式扫描和处理语言

帝国CMS7.0新增了多值字段。像下载地址、在线地址、图片集等这样的将多个内容存放到一个字段的功能,增加字段时选择多值表单元素即可,功能更强大,扩展更灵活。

(一)awk的基本语法概念

  • 澳门新葡亰手机版,基本格式:

awk [options] 'program' file…
awk [options] -f program_file file…
  • program通常由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块,共3部分组成,通常放置于单引号或双引号中

    • program格式:BEGIN{ action;… } pattern{ action;… } END{ action;…
      }
    • pattern:决定动作语句何时触发及触发事件
    • action statements:对数据进行处理,放在{}内指明
  • 选项:
    -F:指明输入时用到的字段分隔符,默认以空格作为分隔符
    -v var=value:自定义变量

  • 分割符、域和记录

    • 文件的每一行称为记录,每一列称为字段(域)
    • awk执行时,由分隔符分隔的字段(域)称为域标识,标记为$1,$2..$n,$0为所有域。
    • 注意:此处的$与shell中变量$符号含义不同
    • 省略action,则默认执行print $0 的操作

支持设定无限列与无限行数据录入,并且支持设置必填的列,以及默认行数。

(二)awk的工作原理

  • 第一步:执行BEGIN{action;… }语句块中的语句

    • BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中
  • 第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ action;…
    }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。

    • pattern语句块中的通用命令是最重要的部分,也是可选的。如果没有提供pattern语句块,则默认执行{
      print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块
  • 第三步:当读至输入流末尾时,执行END{action;…}语句块

    • END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块

结构分析

(三)print语句

  • 语法:print item1, item2, …

    • 逗号分隔符
    • 输出的各item可以字符串,也可以是数值;当前记录的字段、变量或awk的表达式
    • 省略item,相当于print $0
  • 示例1-1:

awk '{print "hello, awk"}'           //等待输入,每输入一条打印一次"hello, awk"
awk '{print}' /etc/passwd            //逐条打印/etc/passwd文件
awk '{print "wang"}' /etc/passwd     //每读入/etc/passwd文件一行,打印一次"wang"
awk -F: '{print $1}' /etc/passwd     //打印/etc/passwd文件以":"作为分隔符的第1列
awk -F: '{print $0}' /etc/passwd     //逐条打印/etc/passwd文件
awk -F: '{print $1,$3}' /etc/passwd  //打印以":"作为分隔符的第1列和第3列,以空格作为分隔符输出
awk -F: '{print $1"t"$3}' /etc/passwd    //打印以":"作为分隔符的第1列和第3列,以制表符作为分隔符输出
tail -3 /etc/fstab | awk '{print $2,$4}'  //打印/etc/fstab文件最后3行以空格作为分隔符的第2列和第4列

trylife熟知帝国CMS数据结构的用户都知道以前的morepic downpath onlinepath
字段储存是如下:

二、awk变量

单行以换行符分割,单项以六个冒号分隔

(一)内置变量

  • FS:输入字段分隔符,默认为空白字符,可以在program中引用
    awk -v FS=':' '{print $1,FS,$3}' /etc/passwd,注意print中的逗号表示1个空格

    • awk变量也可以引用Shell变量,便于脚本编写
      fs=":" ; awk -v FS=$fs '{print $1,FS,$3}' /etc/passwd

澳门新葡亰手机版 1

  • OFS:输出字段分隔符,默认为空白字符
    awk -v FS=':' -v OFS=':' '{print $1,$3,$7}' /etc/passwd

澳门新葡亰手机版 2

  • RS:输入记录分隔符,指定输入时的换行符,原换行符仍有效
    awk -v RS=':' '{print $1}' /etc/passwd

    • 注意到当指定以”:”作为记录分隔符时,输出每条记录的第1个字段时,除了第1条记录外,其他记录的用户名信息都丢失了。

    澳门新葡亰手机版 3

    • 原因在于文件每一行行尾的换行符,当指定其他符号为记录分隔符后,其自身的换行功能得到保留,所以每一行行尾的shell信息和下一行的用户名信息被视作为一条记录,而记录的第一个字段为bash信息,用户名信息没有打印。

澳门新葡亰手机版 4

  • ORS:输出记录分隔符,输出时用指定符号代替换行符
    awk -v RS=':' -v ORS='###' '{print }' /etc/passwd

    • 下图红框的两端内容之间没有”###”分隔,证明属于一条记录,出现的换行证明原文件行尾的换行符功能仍旧保留,再次印证上文所述

    澳门新葡亰手机版 5

  • NF:字段数量

    • awk '{print NF,$0}' /etc/fstab,打印每一行并在行首标明所在行字段数量(以空格为字段分隔符)

    澳门新葡亰手机版 6

    • awk -F: '{print $(NF-1)}' /etc/passwd,打印每行倒数第2个字段(以冒号为字段分隔符)

    澳门新葡亰手机版 7

  • NR:行号

    • awk '{print NR,$0}' /etc/fstab,打印每行的行号

    澳门新葡亰手机版 8

    • awk '{print NR,$0}' /etc/fstab /etc/inittab可以同时打印多个文件,但是行号连续编写

    澳门新葡亰手机版 9

  • FNR:各文件分别计数,行号
    awk '{print FNR,$0}' /etc/fstab /etc/inittab

澳门新葡亰手机版 10

  • FILENAME:当前文件名
    awk '{print FILENAME}' /etc/fstab

澳门新葡亰手机版 11

  • ARGC:命令行参数的个数
    awk 'BEGIN {print ARGC}' /etc/fstab /etc/inittab
    每个红框内容被视作一个参数

    澳门新葡亰手机版 12

  • ARGV:数组,保存的是命令行所给定的各参数
    awk 'BEGIN {print ARGV[0]}' /etc/fstab /etc/inittab
    awk 'BEGIN {print ARGV[1]}' /etc/fstab /etc/inittab
    awk 'BEGIN {print ARGV[2]}' /etc/fstab /etc/inittab

澳门新葡亰手机版 13

a::::::b::::::c::::::d::::::/r/na2::::::b2::::::c2::::::d2::::::/r/n

(二)自定义变量

  • 自定义变量区分大小写,有两种定义方式

    • -v 选项定义
    • 在program中定义
  • 实验:自定义变量的使用

    • awk -v test='hello, gawk' 'BEGIN{print test}',直接使用v选项定义
    • awk 'BEGIN{test="hello, gawk";print test}',在program中定义

    澳门新葡亰手机版 14

    • awk -F: '{sex="male";print $1,sex,age;age=18}' /etc/passwd
      首行没有第3个字段,因为打印首行第3个字段后才对其变量进行了赋值,之后每一行打印时变量已经赋值,可以正常显示

    澳门新葡亰手机版 15

    • 也可以将program部分写入文件中,使用awk的-f选项导入

echo '{print script,$1,$2}' > awkscript
awk -F: -f awkscript -v script="awk" /etc/passwd

澳门新葡亰手机版 16

帝国CMS7.0的多值字段储存则是这样大的

三、printf命令:实现格式化输出

  • 语法:printf “FORMAT”, item1, item2, …

    • 必须指定FORMAT
    • 不会自动换行,需要显式给出换行控制符:n
    • FORMAT中需要分别为后面每个item指定格式符
  • 格式符:与item对应

    • %c:显示字符的ASCII码
    • %d, %i:显示十进制整数
    • %e, %E:显示科学计数法数值
    • %f:显示为浮点数
    • %g, %G:以科学计数法或浮点形式显示数值
    • %s:显示字符串
    • %u:无符号整数
    • %%:显示%自身
  • 修饰符:

    • #[.#]:第一个#控制显示的宽度,第二个#表示小数点后精度,%3.1f
    • -:左对齐(默认右对齐)%-15s
    • +:显示数值的正负符号%+d
  • 实验:printf的使用

    • 显示/etc/passwd文件以冒号为分隔符的第1,3列,并且第1列宽20左对齐,第3列宽10右对齐
      awk -F: '{printf "%-20s %10dn",$1,$3}' /etc/passwd

    澳门新葡亰手机版 17

    • 显示/etc/passwd文件以冒号为分隔符的第1,3列,格式:”Username:
      第1列内容 , ID: 第3列内容”,其中第1列内容宽15左对齐
      awk -F: '{printf "Username: %-15s,ID: %dn",$1,$3}' /etc/passwd

    澳门新葡亰手机版 18

单行以六个竖线分割,单项以六个六个冒号分割。

四、操作符

  • 算术操作符:
    x+y, x-y, x*y, x/y, x^y, x%y
    -x: 转换为负数
    +x: 转换为数值

  • 赋值操作符:
    =, +=, -=, *=, /=, %=, ^=
    ++, —

  • 比较操作符:
    ==, !=,>, >=, <, <=

  • 模式匹配符:
    ~:左边是否匹配右边
    !~:左边是否不匹配右边
    示例:
    awk -F: '$0 ~ /root/{print $1}' /etc/passwd
    打印/etc/passwd文件包含”root”内容行的第一个字段(以”:”分隔)
    awk '$0 ~ "^root" ' /etc/passwd
    打印/etc/passwd文件行首为”root”的行
    awk '$0 !~ /root/' /etc/passwd
    打印/etc/passwd文件不包含”root”内容的所有行
    awk -F: '$3==0' /etc/passwd
    打印/etc/passwd文件以”:”分隔的第三个字符等于0的所有行

  • 逻辑操作符:与&&,或||,非!
    示例:
    awk -F: '$3>=0 && $3<1000 {print $1}' /etc/passwd
    打印root用户和系统用户名称(CentOS 7)
    awk -F: '$3==0 || $3>=1000 {print $1}' /etc/passwd
    打印root用户和普通用户的名称(CentOS 7)
    awk -F: '!($3==0){print $1}' /etc/passwd
    打印除root用户外的所有用户名称
    awk -F: '!($3>=500) {print $3}' /etc/passwd
    打印root用户和系统用户的UID(CentOS 6)

  • 函数调用:function_name(argu1, argu2, …)

  • 条件表达式(三目表达式):
    selector?if-true-expression:if-false-expression
    示例4-1:
    awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s: %-sn",$1,usertype}' /etc/passwd
    打印用户名称,若是普通用户则其后输出”Common User”,否则输出”Sysadmin
    or
    SysUser”,中间以”:”分割。用户名称宽20右对齐,其后的类型信息左对齐(CentOS
    7)

澳门新葡亰手机版 19

a::::::b::::::c::::::d::::::||||||a2::::::b2::::::c2::::::d2::::::

五、awk pattern

  • PATTERN:根据pattern条件,过滤匹配的行,再做处理
    • 如果未指定:空模式,匹配每一行

内容页调用

(一)正则表达式:/regular expression/

仅处理模式匹配到的行,需要用”/ /”括起来

?php/* 内容页调用多值字段示例 trylife@diguoCMS.com 20130513 假设字段这个多值字段为tl**/$exp=explode('||||||',$navinfor[tl]);foreach($exp as $k=$v){ /*下一行是分割多值字段的每行中的每项*/ $exp2=explode('::::::',$v); /* $exp2[0] $exp2[1] 以此类推分别是每行的第一个值 第二个值 第三个值 */ echo 'li'.$exp2[0].' '.$exp2[1].'/li';}?

(二)关系表达式:结果为“真”才会被处理

真:结果为非0值,非空字符串
假:结果为空字符串或0值

(三)行范围

/pat1/,/pat2/:支持使用正则表达式描述,不支持直接给出数字格式

(四)BEGIN/END模式

BEGIN{}:仅在开始处理文件中的文本之前执行一次
END{}:仅在文本处理完成之后执行一次

示例5-1:pattern中正则表达式和关系表达式的用法

  • awk '/^UUID/{print $1}' /etc/fstab
    打印/etc/fstab文件以UUID开头的行的第1列

澳门新葡亰手机版 20

  • awk '!/^UUID/{print $1}' /etc/fstab
    打印/etc/fastab文件不以UUID开头的行的第1列

  • awk -F: 'i=1;j=1{print i,j}' /etc/passwd
    本条命令是awk -F: 'i=1{print $0};j=1{print i,j}' /etc/passwd的简化,program第1条语句关系判断为真(i=1),故打印本行;第2条语句关系判断为真(j=1),故打印i和j值

澳门新葡亰手机版 21

  • awk '!0' /etc/passwd; awk '!1' /etc/passwd
    打印全部行;一行也不打印

  • awk -F: '$3>=1000{print $1,$3}' /etc/passwd
    打印/etc/passwd文件以”:”为分隔符的第3列数值大于等于1000的行的第1和第3列

  • awk -F: '$3<1000{print $1,$3}' /etc/passwd
    打印/etc/passwd文件以”:”为分隔符的第3列数值小于1000的行的第1和第3列

  • awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
    打印/etc/passwd文件以”:”为分隔符的最后一列是”/bin/bash”的行的第1列和最后1列

  • awk -F: '$NF~ /bash$/{print $1,$NF}' /etc/passwd
    打印/etc/passwd文件以”:”为分隔符的最后一列是以”bash”作为行尾的行的第1列和最后1列

  • seq 10 | awk 'i=!i'
    读入第1行时,i值取反为1所以打印本行,读入第2行时,i值为1取反后为0所以不打印本行,读入第3行与读入第1行相似,读入第4行与读入第2行相似,以此类推,所以结果为打印奇数行

澳门新葡亰手机版 22

  • seq 10 | awk '!(i=!i)'seq 10 | awk -v i=1 'i=!i'
    与上文类似,结果为打印偶数行

澳门新葡亰手机版 23