Linux 如何在unix中搜索和替换特定列中的值
我正在AIX中编写一个shell脚本,其中包含一些代码来更新文本文件中的某些值。 该文件的格式如下所示:Linux 如何在unix中搜索和替换特定列中的值,linux,shell,perl,unix,aix,Linux,Shell,Perl,Unix,Aix,我正在AIX中编写一个shell脚本,其中包含一些代码来更新文本文件中的某些值。 该文件的格式如下所示: # cat $FILE instance1 13 16 instance2 14 12 instance4 58 76 instance15 44 91 instance102 31 10 instance112 12 38 我正在尝试按实例名称搜索,并用新值替换第2列和第3列中的值 我可以使用perl进行如下操作: # for i in `cat $FILE|a
# cat $FILE
instance1 13 16
instance2 14 12
instance4 58 76
instance15 44 91
instance102 31 10
instance112 12 38
我正在尝试按实例名称搜索,并用新值替换第2列和第3列中的值
我可以使用perl进行如下操作:
# for i in `cat $FILE|awk '{print $1}'`;do
# perl -pi -e "s/`grep -i $i $FILE|awk '{print $2}'`/$NEW_VAL_2/ if /$i/" $FILE
# perl -pi -e "s/`grep -i $i $FILE|awk '{print $3}'`/$NEW_VAL_3/ if /$i/" $FILE
# done
这是可行的,但后来我意识到它正在取代每一次出现的值。例如,在最后一行中,它将替换第2列中的值以及实例名称的最后两个字符
Example:
# i = instance112
# NEW_VAL_2 = 99
# perl -pi -e "s/`grep -i $i $FILE|awk '{print $2}'`/$NEW_VAL_2/ if /$i/" $FILE
Output:
instance199 99 38
如何按实例名称搜索行并仅替换特定列中的值?在awk中
awk -v newval="$NEW_VAL_2" -v i="$i" '
BEGIN{OFS="\t"}
$1 == i { $2 = newval } 1' $FILE > newfile
<>请参阅更多关于<代码> -v>代码>,以及为什么它比试图在脚本字符串中间插入变量更好。 <>在AWK中;
awk -v newval="$NEW_VAL_2" -v i="$i" '
BEGIN{OFS="\t"}
$1 == i { $2 = newval } 1' $FILE > newfile
<>请参阅更多关于<代码> -v>代码>,以及为什么它比试图在脚本字符串中间插入变量更好。 这里是Perl一个线性解决方案。在这里使用纯perl(带有模式匹配)比混合使用grep、awk和perl更容易、更快
$ export FILE=foo
$ cat $FILE
instance1 13 16
instance2 14 12
instance4 58 76
instance15 44 91
instance102 31 10
instance112 12 38
$ export i=instance112
$ export NEW_VAL_2=99
$ export NEW_VAL_3=11
$ perl -lne 'if ( m{ \A $ENV{i} \t }xms ) { $_ = join "\t", @ENV{ qw( i NEW_VAL_2 NEW_VAL_3 ) }; } print; ' foo
instance1 13 16
instance2 14 12
instance4 58 76
instance15 44 91
instance102 31 10
instance112 99 11
下面是一个perl单行程序解决方案。在这里使用纯perl(带有模式匹配)比混合使用grep、awk和perl更容易、更快
$ export FILE=foo
$ cat $FILE
instance1 13 16
instance2 14 12
instance4 58 76
instance15 44 91
instance102 31 10
instance112 12 38
$ export i=instance112
$ export NEW_VAL_2=99
$ export NEW_VAL_3=11
$ perl -lne 'if ( m{ \A $ENV{i} \t }xms ) { $_ = join "\t", @ENV{ qw( i NEW_VAL_2 NEW_VAL_3 ) }; } print; ' foo
instance1 13 16
instance2 14 12
instance4 58 76
instance15 44 91
instance102 31 10
instance112 99 11
将
ITEM
作为要修改的实例行。让NV2
和NV3
作为第2和第3个字段的新值
下面是一个例子:
ITEM=instance102; NV2=100; NV3=80; sed -E -e "s/^${ITEM}(\\s+)(\\S+)(\\s+)(\\S+)(\\s*)\$/${ITEM}\\1${NV2}\\3${NV3}\\5/" $FILE
它还保留了原始的间距字符:可以是制表符、空格,也可以是制表符和空格的组合。即使不同的行使用不同的间距样式,它也会保持原始间距。让
项
作为要修改的实例行。让NV2
和NV3
作为第2和第3个字段的新值
下面是一个例子:
ITEM=instance102; NV2=100; NV3=80; sed -E -e "s/^${ITEM}(\\s+)(\\S+)(\\s+)(\\S+)(\\s*)\$/${ITEM}\\1${NV2}\\3${NV3}\\5/" $FILE
它还保留了原始的间距字符:可以是制表符、空格,也可以是制表符和空格的组合。即使对不同的线使用不同的间距样式,它也会保持原始间距