我有这个:
odds = [i for i in range(1,21) if i % 2 == 0]
even = [i for i in range(1,21) if i % 2 != 0]
这给了我:(#1)
$ cat f2
123-foo-456
abc-xx
foo-yy
ddd-ao
abc
6778
123
这给了我:(#2)
$ sed -n -e '/456/,/ddd/{/ddd/{!s/a/A/g;!s/o/Q/g};p}' f2
123-foo-456
abc-xx
foo-yy
ddd-ao
我更喜欢#2,因为它做了我想要的输出。
有人可以解释两者之间的区别吗? 一个很好的文档来源解释了差异?
答案 0 :(得分:2)
/ddd/{!s/a/A/g;!s/o/Q/g}
ddd
在线上时(工作缓冲区)
{ ...}
!
)地址(空地址表示每行都没有行)替代(s/a/A/g
)... 所以它什么都不做
/ddd/!{s/a/A/g;s/o/Q/g}
ddd
NOT 时(工作缓冲区)(!
用于地址/模式/ddd/
)
{ ...}
s/a/A/g
),... 它将a
更改为A
,但不包含ddd
答案 1 :(得分:1)
2之间没有值得注意的区别。它们都是无法理解的随机字符序列,在1970年代中期发明awk时已经过时,因此永远不应该使用。 sed用于单个行上的简单替换,即全部。如果您使用的不仅仅是s,g和p(使用-n),那么您使用了错误的工具。不要再浪费你的时间了,只需使用awk:
$ cat tst.awk
/456/ { f=1 }
f {
if (/ddd/) {
f=0
}
else {
gsub(/a/,"A")
gsub(/o/,"Q")
}
print
}
$ awk -f tst.awk file
123-fQQ-456
Abc-xx
fQQ-yy
ddd-ao
清晰,简洁,简洁,强大,高效,便携,并且在其他方面比同等的sed解决方案更好。
或者如果把所有东西挤到一条线上对你很有吸引力:
$ awk '/456/{f=1}f{if(/ddd/)f=0;else{gsub(/a/,"A");gsub(/o/,"Q")}print}' file
123-fQQ-456
Abc-xx
fQQ-yy
ddd-ao
您可以使用与sed脚本相同的样式编写awk脚本:
$ awk '/456/,/ddd/{if(!/ddd/){gsub(/a/,"A");gsub(/o/,"Q")}print}' file
123-fQQ-456
Abc-xx
fQQ-yy
ddd-ao
然后你得到了使用范围表达式的重复条件(/ddd/
两次),这是它们永远不应该被使用的一个原因。幸运的是,与sed不同,awk具有变量,因此您永远不需要编写范围表达式。