2012-12-12 98 views
0

我有一個文本文件,其中有4列用逗號分隔。 當我讀循環中的每條記錄時,我想根據條件向第5列添加一個值。 因此,如果我知道行號和列號,如何在不使用臨時文件的情況下使用awk/sed命令替換/設置該特定字段的值? 我想更新的文件(直接),我從unix sed,在同一個文件的特定行和列中替換字段

inp.txt 
a,b,c,d 
e,f,g,h 
i,j,k,l 

謝謝閱讀, -SRI

回答

2

您不能直接編輯使用任何awksed文件。 sed的某些版本有一個選項(-i),該選項與臨時文件一起使用並覆蓋原始文件,但它實際上並未就地編輯該文件。這不是什麼大不了的事。只要做到:

$ awk 'NR==5{ $(NF+1) = "new value"}1' OFS=, FS=, input-file > tmp.$$ 
$ mv tmp.$$ input-file 

要添加新的列行input-file 5。如果您願意,可以使用ed來編輯文件,但使用臨時文件更有意義。如果你想假裝你不使用臨時文件,和您的SED支持-i,你可以做同樣的事情:

sed -i '5s/$/,new value/' input-file 

即使大多數utilitites不允許文件的就地修改,它是簡單使用以下sh功能之一使用臨時文件來模仿這種行爲:

edit() { local f=$1; shift; "[email protected]" < $f > $f.$$ && mv $f.$$ $f; } # Break hard links 
edit() { local f=$1; shift; "[email protected]" < $f > $f.$$ && cat $f.$$ > $f && rm $f.$$; } 

在上述任一情況,你可以使用awk給編輯文件就地使用edit filename awk awk-cmds外觀。第一個版本打破硬鏈接,但使用略少的IO。

2

我不能說sed,但awk的目的不是編輯文件,而是寫入標準輸出。

但無論如何,這裏有一個解決方案,你不需要循環,假裝條件是第4列中的條目是h。

awk -F ',' '{ if ($4 == "h") print $0",z"; else print $0","}' inp.txt > out.txt 

輸出:

a,b,c,d, 
e,f,g,h,z 
i,j,k,l, 
+0

上面可以更簡明地作爲寫入:'awk -F',''{print $ 0 FS($ 4 ==「h」?「z」:「」)}'inp.txt> out.t xt' –

0

你的意思是這樣嗎? 這是該版本不使用任何臨時文件。

[[email protected] ~]$ cat tmp | sed 's_^\(.*\),\(.*\),\(.*\),\(.*\)_\1,\2,\3,\4_g' 
inp.txt 
a,b,c,d 
e,f,g,h 
i,j,k,l 

[[email protected] ~]$ cat tmp | sed 's_^\(.*\),\(.*\),\(.*\),\(.*\)_\1,sth,\3,\4_g' 
inp.txt 
a,sth,c,d 
e,sth,g,h 
i,sth,k,l 

[[email protected] ~]$ sed -ie 's_^\(.*\),\(.*\),\(.*\),\(.*\)_\1,sth,\3,\4_g' tmp 
[[email protected] ~]$ cat tmp 
inp.txt 
a,sth,c,d 
e,sth,g,h 
i,sth,k,l 

乾杯,

+1

它使用臨時文件。檢查你的sed文檔。 –

+0

謝謝。我學到了一件新事物。 – tsohr

1
perl -i -F, -lane 'if($.==<row number>){$F[<column_number>-1]+=<add your stuff here>}print join(",",@F)' your_file 

測試下面:

>cat temp 
b,c,d,g 
r,g,d,s 

執行用於在第二行改變第三柱:

>perl -i -F, -lane 'if($.==2){$F[2]=10}print join(",",@F)' temp 
> cat temp 
b,c,d,g 
r,g,10,s