2

我喜欢 awk 的地方在于,您可以从满足您指定的某些字段的条件的文件中获取所有行。例如,

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 强大功能的初学者,我对此非常着迷。现在我想知道是否有一种简单的方法可以仅在您指定的某些任意字段上执行正则表达式替换?例如,我只想对第三个字段进行正则表达式替换。我目前的方法是“剪切”我想要的字段并使用 perl 或 sed 对其执行替换,然后我将其“粘贴”到原始文件中。但我想知道是否有更有效的方法来实现这一目标。

谢谢

4

3 回答 3

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
于 2012-05-23T06:07:04.290 回答
3

这可能对您有用:

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

您可以使用sub,gsub命令或这种情况:

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

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

注意1行尾的 是 的简写{print}

于 2012-05-23T06:37:36.123 回答
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被替换x为第三列中的$3
-F ","设置输入文件的分隔符。 OFS=","在输出中添加一个逗号。

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

高温高压

于 2012-05-23T07:08:14.417 回答