2013-09-24 33 views
0

我必须更新文件中特定唯一标识的列值。 我的文件名和样本内容如下:如何刷新行并更新特定列值

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命令没有给出结果。请帮我解决这个错误。

+0

虽然我已经工作了另一种方式来得到的结果,但我想找出这个错误。 在此先感谢 – Learner

+1

你究竟在做什么?你的专栏如何修改? – konsolebox

+1

您的发布脚本显然不起作用。你用什么值来更新'Names.txt'中的第4列? – anubhava

回答

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 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 } 
' "[email protected]" 

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

非常感谢您的回复,现在查询正在运行。 我不明白我的脚本有什么性能问题或错误的方法,您可以帮助解决这个问题.. – Learner

+0

您的目标是操纵文本文件的内容。创建shell是为了创建/销毁进程和文件,以及对UNIX工具的调用顺序。 awk是为处理文本文件而创建的通用UNIX工具,可在所有UNIX安装中使用。您的shell脚本以及无法使用的功能很长,很复杂,有问题,不可移植,资源密集并且速度很慢,因为您使用了错误的工具。每次你在shell中编写一个循环来操纵文本文件的内容时,你都会犯错。 –

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 
+0

感谢您的帮助 BUt can you帮助找出我的脚本中的错误 ,因为而不是变量如果我直接使用它正在工作的值,唯一的问题是使用变量 – Learner

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 
+0

我不必取代每个值,但一些特定的值,如超出3值可能是J011,该文件可能包含1000个条目,所以我需要一般解决方案 感谢您的帮助.. – Learner

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 
+0

感谢您回复 它不起作用。 我很好奇在我自己的查询中找到用于grep结果的缺陷 – Learner