sedを使用した複数の特定のイベントの交換

sedを使用した複数の特定のイベントの交換

現在、構造の大容量CSVファイルがあります。

380670000001,<n>,0,1970-01-01 00:00:00.00+0000,0,0,<n>,0,0

交換する必要があります "<n>"2列と4列「1970-01-01 00:00:00.00+0000」
交換して"<n>"別の列に0

現在、私は使用していますアッスクリプト:

awk 'BEGIN{FS=OFS=","}{sub("<n>","1970-01-01 00:00:00.00+0000",$2); sub("<n>","1970-01-01 00:00:00.00+0000",$4);  gsub("<n>", 0); print}' input.txt > output.txt

もっとエレガントにできますか?sed

答え1

私はそうは思わない。 sedにはフィールドのようなものがないので、ハードカウントに正規表現を使用する必要があります。できますが、十分にエレガントではありません。

r='1970-01-01 00:00:00.00+0000'
sed -E "s/^([^,]*,)<n>/\1$r/;s/^(([^,]*,){3})<n>/\1$r/;s/<n>/0/g" file

(確認したい場合があります。パターンの一部を保存するには\ 1を使用してください。逆参照について知らない場合。 )

上でsedにしたように、シェル変数を設定してからawkに渡してawkをクリーンアップできます。したがって、awkスクリプトには主にロジックのみが含まれます。

r='1970-01-01 00:00:00.00+0000'
m='<n>'
awk 'BEGIN{FS=OFS=","}{sub(m,r,$2);sub(m,r,$4);gsub(m,"0")}1' r="$r" m="$m" file

短い:

awk -F, '{sub(m,r,$2);sub(m,r,$4);gsub(m,"0")}1' OFS=, r="$r" m="$m" file

答え2

いいえ、sedを使用するとこれよりもエレガントにすることはできませんが、awkではよりエレガントに実行できます。

$ awk '
    BEGIN { FS=OFS=","; n="<n>"; r="1970-01-01 00:00:00.00+0000" }
    { for (i=2;i<=4;i+=2) if ($i == n) $i=r; gsub(n,0) }
1' file
380670000001,1970-01-01 00:00:00.00+0000,0,1970-01-01 00:00:00.00+0000,0,0,0,0,0

答え3

次のawkコマンドを試してください

echo "380670000001,<n>,0,1970-01-01 00:00:00.00+0000,0,0,<n>,0,0"| awk -F "," '{for(i=1;i<=NF;i++){if(i ~ /2|4/){gsub("<n>","1970-01-01 00:00:00.00+0000",$i)}else{gsub("<n>","0") }}}1'

出力

380670000001,0,0,1970-01-01 00:00:00.00+0000,0,0,0,0,0

関連情報