Linux/UNIXでsed or awkを使ってファイルの特定列だけ置き換える

LinuxやUNIXで、区切り文字で句切られているファイルの、特定の列だけ値を置き換える場合は、sedかawkを用いる事で楽に行う事ができる。

sedで行う場合

sedで特定列のみ置き換える場合は、以下のようにコマンドを実行する。

sed '{s/"区切り文字"[^"区切り文字"]*}/"区切り文字"置換後の文字/置き換える列-1} 対象ファイル

例えば、「,(カンマ)」で句切られたファイルの3列目を「hige」に置き換える場合だと、以下のように記述する。

sed '{s/,[^,]*/,hige/2}' 対象ファイル

[root@localhost ~]# cat /tmp/test.file
aaaaa,11111,super,66666661
bbbbb,22222,wonder,66666662
ccccc,33333,dorderar,66666663
ddddd,44444,atacker,66666664
eeeee,55555,pepsi,66666665
fffff,66666,papet,66666666
ggggg,77777,dagashikasi,66666667
hhhhh,88888,goemon,66666668

[root@localhost ~]# sed '{s/,[^,]*/,hige/2}' /tmp/test.file
aaaaa,11111,hige,66666661
bbbbb,22222,hige,66666662
ccccc,33333,hige,66666663
ddddd,44444,hige,66666664
eeeee,55555,hige,66666665
fffff,66666,hige,66666666
ggggg,77777,hige,66666667
hhhhh,88888,hige,66666668

特定の行のみを置き換える場合は、以下のように行の条件を指定する。
例えば、「bbbbb」で始まる列を置き換える場合は以下のようにする。

sed '/^bbbbb/{s/,[^,]*/,hige/2}' 対象ファイル

[root@localhost ~]# sed '/^bbbbb/{s/,[^,]*/,hige/2}' /tmp/test.file
aaaaa,11111,super,66666661
bbbbb,22222,hige,66666662
ccccc,33333,dorderar,66666663
ddddd,44444,atacker,66666664
eeeee,55555,pepsi,66666665
fffff,66666,papet,66666666
ggggg,77777,dagashikasi,66666667
hhhhh,88888,goemon,66666668

awkで行う場合

awkで行う場合は、もっと簡単に行える。

awk '{FS="区切り文字";OFS="区切り文字"}{$置き換える列番号="置換後の文字列"}1' 対象ファイル

例えば、2列目を「999000」に置換する場合、以下のようにコマンドを実行する。

awk '{FS=",";OFS=","}{$2="999000"}1' 対象ファイル

[root@localhost ~]# cat /tmp/test.file
aaaaa,11111,super,66666661
bbbbb,22222,wonder,66666662
ccccc,33333,dorderar,66666663
ddddd,44444,atacker,66666664
eeeee,55555,pepsi,66666665
fffff,66666,papet,66666666
ggggg,77777,dagashikasi,66666667
hhhhh,88888,goemon,66666668

[root@localhost ~]# awk 'BEGIN {FS=",";OFS=","}{$2="999000"}1' /tmp/test.file
aaaaa,999000,super,66666661
bbbbb,999000,wonder,66666662
ccccc,999000,dorderar,66666663
ddddd,999000,atacker,66666664
eeeee,999000,pepsi,66666665
fffff,999000,papet,66666666
ggggg,999000,dagashikasi,66666667
hhhhh,999000,goemon,66666668
,999000

特定の行にしぼって更新する場合は、以下のように条件をつけると良いだろう。
以下の例では、3列目が「pepsi」の行のみ、2列目を置換するように指定している。

[root@localhost ~]# awk 'BEGIN {FS=",";OFS=","}$3=="pepsi"{$2="999000"}1' /tmp/test.file
aaaaa,11111,super,66666661
bbbbb,22222,wonder,66666662
ccccc,33333,dorderar,66666663
ddddd,44444,atacker,66666664
eeeee,999000,pepsi,66666665
fffff,66666,papet,66666666
ggggg,77777,dagashikasi,66666667
hhhhh,88888,goemon,66666668