2013-09-24 70 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