2012-05-23 20 views
2

我喜欢awk的是,您可以从文件中获取满足您指定的某个任意字段上的条件的所有行。 例如,如何在您指定的某个任意字段上执行regex替换

awk '$3~/hi/' < test.txt # print all lines where the third field matches the pattern "hi" 

awk '$2>=2' < test.txt # print all lines where the second field is greater or equal to 2 

至于谁是学习UNIX的强大初学者,我绝对着迷此。 现在我想知道是否有一种简单的方法来执行正则表达式替换只在您指定的一些任意字段?例如,我只想在第三个字段上进行regex替换。 我目前的方法是“剪切”我想要的字段并使用perl或sed执行替换,然后将其“粘贴”到原始文件。但我想知道是否有更有效的方法来实现这一点。

感谢

回答

4

既然你标有“perl的”这个问题(除了“sed的”,“AWK”,“UNIX”和“命令行”),我会假设你有兴趣在包含任何上述工具的答案中。

Perl有自动分割命令行开关(-a):

perl -lane 'print if $F[2] =~ /some pattern/' filename 

...或...

perl -lane 'print if $F[1] >= 42' filename 

-a导致自动分割成@F阵列。 -n会导致Perl遍历您提供的文件的行。剩下的就是编程。 )

现在对于取代:

perl -i.bak -lane '$F[2] =~ s/match/subst/; print join q/ /, @F' filename 

或者,使用-p开关,它告诉Perl因为它出现在$_打印每行短一些。这意味着如果你改变@F,你必须回到其复制到$_

perl -i.bak -pale '$F[2] =~ s/match/subst/ && $_="@F"' filename 
3

这可能会为你工作:

echo -e 'Fred barney Wilma\nfoo bar baz' | 
awk '$2 == "barney"{sub(/b/,"B",$2)};1' 
Fred Barney Wilma 
foo bar baz 

可以使用subgsub命令或此这种情况下, :

echo -e 'Fred barney Wilma\nfoo bar baz'| 
awk '$2 == "barney"{$2="Barney"};1' 
Fred Barney Wilma 
foo bar baz 

只是完全替换第二个字段。

N.B.该行末尾的1{print}的简写。

1

考虑一个简单的例子:

awk -F "," '{ OFS=","; sub ("1", "x", $3); print $0 }' file.txt > newfile.txt

newfile.txt现在将包含:

1,2,3,4,5,6,7 
8,9,x0,11,12,13,14 
15,16,x7,18,19,20,21 

这里,1在第三列$3x代替。
-F ","设置输入文件的分隔符。 OFS=","向输出添加逗号。

如果您想在全球范围内进行替换,请考虑使用gsub而不是sub

HTH

+1

我认为这将是更好的一次读取输入文件中的'BEGIN'块,像'AWK -F之前设置'OFS'值 “”“BEGIN {OFS = “” } {sub ...}'' – Birei

相关问题