如何在unix中的特定列中搜索和替换值

问题描述 投票:1回答:3

我正在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|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

如何通过实例名称搜索行并仅替换特定列中的值?

linux shell perl unix aix
3个回答
0
投票

awk;

awk -v newval="$NEW_VAL_2" -v i="$i" '
  BEGIN{OFS="\t"}
  $1 == i { $2 = newval } 1' $FILE > newfile

有关How do I use shell variables in an awk script的更多信息,请参见-v,为什么它比尝试在脚本字符串的中间插入变量更好。


0
投票

这里是一个perl单线解决方案。与grep,awk和perl的混合使用相比,在这里使用纯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

0
投票

ITEM为要修改的实例行。令NV2NV3为第二和第三字段的新值。

这里是一个例子:

ITEM=instance102; NV2=100; NV3=80; sed -E -e "s/^${ITEM}(\\s+)(\\S+)(\\s+)(\\S+)(\\s*)\$/${ITEM}\\1${NV2}\\3${NV3}\\5/" $FILE

它还保留了原始的空格字符:制表符,空格或制表符和空格的组合。即使对于不同的线条使用不同的间距样式,它也可以保持原始间距。

© www.soinside.com 2019 - 2024. All rights reserved.