Perl 如何仅在指定的任意字段上进行正则表达式替换

Perl 如何仅在指定的任意字段上进行正则表达式替换,perl,unix,command-line,sed,awk,Perl,Unix,Command Line,Sed,Awk,我喜欢awk的地方在于,您可以从满足您指定的算术字段条件的文件中获取所有行。 比如说, awk '$3~/hi/' < test.txt # print all lines where the third field matches the pattern "hi" awk'$3~/hi/'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在第三列3中被替换为

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

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

awk'$2>=2'
作为一个正在学习unix功能的初学者,我对此非常着迷。 现在我想知道是否有一种简单的方法可以只在您指定的一些任意字段上执行正则表达式替换?例如,我只想对第三个字段进行正则表达式替换。 我当前的方法是“剪切”我想要的字段,并使用perl或sed对其执行替换,然后将其“粘贴”到原始文件中。但我想知道是否有更有效的方法来实现这一点


谢谢

因为您用“perl”(除了“sed”、“awk”、“unix”和“command-line”)标记了这个问题,所以我假设您对包含上述任何工具的答案感兴趣

Perl有一个自动拆分命令行开关(
-a
):

……或者

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
,则必须将其复制回
$\ucode>:

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

这可能适合您:

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}

的简写,请考虑一个简单的例子:

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
在第三列
3
中被替换为
x
-F“,”
设置输入文件的分隔符。
OFS=“,”
在输出中添加逗号

如果您想在全局上进行替换,请考虑使用<代码> GSUB/COD>而不是<代码>子< /代码> ./P>


HTH

我认为最好在读取
BEGIN
块中的输入文件之前设置一次
OFS
的值,比如
awk-F“,”BEGIN{OFS=“,”}{sub…}”
echo -e 'Fred barney Wilma\nfoo bar baz'|
awk '$2 == "barney"{$2="Barney"};1'
Fred Barney Wilma
foo bar baz
1,2,3,4,5,6,7
8,9,x0,11,12,13,14
15,16,x7,18,19,20,21