- 论坛徽章:
- 49
|
谢谢各位评委的辛苦总结,下面是参考答案:- 1:
- FS是field separator, 默认下它代表空白字符集,包括空格,TABs和newline,而不是一个空格,可以理解为FS=[ \t\n]+。
- awk -F ' ' '{CMD' 等价于 awk '{CMD}'
- awk -F '[ ]' FS代表单个空格,如果行首为空格,则第一个域(field)为空值。
- awk -F '[ ]+' FS代表多个连续空格。
- 示例:
- 字符串:' (两个空格)foo1 foo2';
- echo ' foo1 foo2' |awk -F ' ' '{print $1,$2}'
- foo1 foo2
- echo ' foo1 foo2' |awk '{print $1,$2}'
- foo1 foo2
- echo ' foo1 foo2' |awk -F '[ ]' '{print $1,$2}'
- echo ' foo1 foo2' |awk -F '[ ]+' '{print $1,$2}'
- foo1
-
- 2:
- 不一样:
- 不管是awk还是sed,默认下表达式/foo1/,/foo2/的布尔值为false
- awk '/foo1/,/foo2/'
- 当/foo1/为真,表达式的布尔值为true,执行其后的action(这里是print),
- 同时判断/foo2/是否为真,如果为真,匹配表达式的布尔值变成false,否则,不改变表达式的布尔值,直到/foo2/匹配为真。
- sed -n '/foo1/,/foo2/p'
- /foo1/为真,表达式的布尔值为true,执行其后的action(p指令),
- 和awk不同的是,sed是在/foo1/匹配为真的下一行,才对/foo2/进行判断,也就当读入下一行时,
- 同样,如果/foo2/为真,匹配表达式的布尔值变成false,否则,不改变表达式的布尔值,直到/foo2/匹配为真。
- 示例:
- cat file
- foo1 foo2
- foo2
- foo1
- xxx
- yyy
- foo2
- zzz
- awk '/foo1/,/foo2/' file
- foo1 foo2
- foo1
- xxx
- yyy
- foo2
- sed -n '/foo1/,/foo2/p' file
- foo1 foo2
- foo2
- foo1
- xxx
- yyy
- foo2
-
- 3:
- echo {a,b,c,e,f}{1,2,3}
- 4:
- echo 'aaabcccaaabbbccccbaaabb' |sed -nr 's/([^\n])\1*/&\n/g;:a;s/(^|\n)([^\n]+)(\n(.*\n)*)\2\n/\1\2\3/;ta;s/\n//gp'
- echo 'aaabcccaaabbbccccbaaabb' |awk -F '' '{while(i++<=NF){s=s$i;if($i!=$(i+1)){if(!a[s]++)printf s;s=""}}}'
- aaabcccbbbccccbb
- 5:
- 因为\<newline>解释在参数展开(parameters expansion)之前。
- 6:
- bash 对不在双引号中的参数展开的结果进行 word splitting 处理: 根据字段分隔符
- 把结果切割为多个word,最后再用单个space连接分割得到的多个word。而多个连续空
- 格被看作一个字段分隔符,所以最后foo与bar之间只有一个空格。
- 7:
- sed -n '/a/{p;:a;n;H;/c/{x;s/\n//p;z;h};ba}' file
- 8:
- seq 9|sed 'N;:a;N;s/\n/ /gp;s/\w* //;ta'
复制代码 |
|