如何grep一行并更新特定的列值

时间:2013-09-24 06:53:42

标签: bash unix sed awk

我必须更新文件中特定唯一ID的特定列值。 我的文件名和样本内容如下:

names.txt中

J017 0001 Jagdeep 10th
J011 2341 Kuldeep 11th
J004 1254 Ramand  12th

我必须将第4列值更新为某些内容。我尝试了以下逻辑,但没有工作

stu="";
for i in `echo "J017, J058 and J107.  " |egrep -o '[jJ][0-9]{3}' `
do
   stu="$stu|$i ";
   awk -v I=$i '/$I/{$4="LEFT";print $0}'  Names.txt >tmp
done


egrep -v `echo "$stu" | sed "s/^|//g" ` Names.txt >>tmp

mv tmp Names.txt

上面的awk命令没有给出结果。请帮我修复错误。

4 个答案:

答案 0 :(得分:3)

回答有关原因的具体问题:

awk -v I=$i '/$I/{$4="LEFT";print $0}'

不起作用,你不要通过在前面添加“$”来访问awk变量,就像你不为C或大多数其他语言(shell是例外)那样。这就是你如何写上面的内容来执行你试图让它执行的方式:

awk -v I=$i '$0 ~ I{$4="LEFT";print $0}'

话虽如此,你的shell脚本完全是错误的方式来做你想要的。试试这个(对于patsplit()使用GNU awk但在其他awks中使用match()/ substr()也可以正常工作):

$ cat tst.sh
awk -v ids="J017, J058 and J107.  " '
BEGIN{
    patsplit(ids,idsA,/[jJ][0-9]{3}/)
    for (i=1;i in idsA;i++)
        stu = stu (i==1?"^":"|") idsA[i]
    stu = stu "$"
}
$1 ~ stu { $4 = "LEFT" }
{ print }
' "$@"

$ ./tst.sh file
J017 0001 Jagdeep LEFT
J011 2341 Kuldeep 11th
J004 1254 Ramand  12th

答案 1 :(得分:2)

#!/bin/bash

FILE='Names.txt'    
COLUMNS=(J017 J011 J004)
REPLACE='LEFT'

OUT=$(
    IFS="|"
    awk -v R="$REPLACE" -v E="${COLUMNS[*]}" '$1 ~ E{$4 = R;print $0}' "$FILE"
)

echo "$OUT" > "$FILE"

使用以下命令运行:

bash script.sh

输入:

J017 0001 Jagdeep 10th
J011 2341 Kuldeep 11th
J004 1254 Ramand  12th

结果:

J017 0001 Jagdeep LEFT
J011 2341 Kuldeep LEFT
J004 1254 Ramand LEFT

答案 2 :(得分:0)

names.txt中

J017 0001 Jagdeep 10th
J011 2341 Kuldeep 11th
J004 1254 Ramand  12th

AWK

awk '/[jJ][0-9][0-9][0-9]/ {$4="LEFT"}1' Names.txt
J017 0001 Jagdeep LEFT
J011 2341 Kuldeep LEFT
J004 1254 Ramand LEFT

答案 3 :(得分:0)

这可能对您有用:

echo "J017, J111 and J004.  " |
grep -o "J[0-9]\{3\}" |
awk 'FNR==NR{key[$1];next};$1 in key{$4="LEFT"}1' - Names.txt