0

コンマで区切られた 4 列のテキスト ファイルがあります。ループで各レコードを読み込んでいるので、条件によっては5列目に値を追加したい。行番号と列番号がわかっている場合、awk/sedコマンドを使用して、一時ファイルを使用せずにその特定のフィールドの値を置換/設定するにはどうすればよいですか? 読み込んでいるファイルを(直接)更新したい

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

ありがとう、-sri

4

4 に答える 4

2

awkまたはを使用してファイルを直接編集することはできませんsed。一部のバージョンにsedは、一時ファイルを処理して元のファイルを上書きするオプション(-i)がありますが、実際にはその場でファイルを編集しません。これは大したことではありません。ただ行う:

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

の行5に新しい列を追加しますinput-file。必要に応じて、を使用edしてファイルを編集できますが、一時ファイルを使用する方が理にかなっています。一時ファイルを使用していないふりをしたい場合で、sedがをサポートしている-i場合は、次の方法で同じことを行うことができます。

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

ほとんどのユーティリティではファイルのインプレース変更は許可されていませんが、次のsh関数のいずれかを使用して、一時ファイルを使用してその動作をエミュレートするのは簡単です。

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

これらのいずれかを使用すると、を使用awkしてファイルをインプレースで編集しているように見せることができますedit filename awk awk-cmds。最初のバージョンはハードリンクを切断しますが、使用するIOはわずかに少なくなります。

于 2012-12-12T01:24:30.717 に答える
2

sed について話すことはできませんが、awk の目的はファイルをその場で編集することではなく、stdout に書き込むことです。

とにかく、これはループを必要としない解決策です。条件は、列 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,
于 2012-12-12T01:26:23.337 に答える
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

2行目の3列目を変更するために実行します。

>perl -i -F, -lane 'if($.==2){$F[2]=10}print join(",",@F)' temp
> cat temp
b,c,d,g
r,g,10,s
于 2012-12-12T06:19:25.750 に答える
0

こんな感じですか?これは、一時ファイルを使用しないバージョンです。

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

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

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

乾杯、

于 2012-12-12T01:34:43.273 に答える