テキストを解析、検索、および置き換える必要がある大容量ファイルがありますが、特定のフィールドでは参照用にdestという小さなサンプルを共有します。最初の行は参照用のタイトルです。
cat dest
ID|NAME|COMPANY|NUMBER
1001|Adam||15001
1002|eve|adam&eve|15002
1003|||
1004|||50000
1005|||50001
一致させるパターン、置換テキスト、置換テキストを含む別々のファイルがあります。
cat src
1003||15003
1004|50000|15004
1005|50001|15005
したがって、sedを使用して、srcファイルの最後の2行に対して以下のwhileループを実行できます。
cat src | while IFS=$'|'; read id old new; do sed -i "/^${id}/s/${old}/${new}/" dest; done
しかし、ID=1003
私が取得した空の文字列の場合、$old
destファイルはそのIDのすべての空の列を置き換えます。私はこのような状況を避けたい。私が望むのは、最後のフィールドだけを変更することです。
期待する:
ID|NAME|COMPANY|NUMBER
1001|Adam||15001
1002|eve|adam&eve|15002
1003|||15003
1004|||15004
1005|||15005
列形式のデータに対してさらに細分化されているため、awkを使用できます。しかし、私が知っている限り、awkはstdoutで何度も印刷しますが、これは私にとっても実用的ではありません。
それでは、この作業を賢く簡潔に行う方法はありますか?
ベストアンサー1
awk 'BEGIN{ FS=OFS="|" }
NR==FNR { id[$1, $2]=$3; next }
{ $4=( ($1, $4) in id? id[$1, $4]: $4) } 1' src dest
FS:F生産するSイテレータ
OFS:酸素出力F生産するSイテレータ
NR==FNR: 最初の入力ファイルに対して常に真である条件付きイディオムです。
NR総存在数窒素数量右FNRが読んだ記録
はすべての人に存在します。Fエリス窒素数量右記録。id[$1, $2]=$3
:関連awk配列。名前:id
キー:列#1 +列#2
値:列#3最初のブロックは、最初の入力ファイルに対してのみ実行されます。ない。書類ソースコード。
ここでは$4=($1, $4) in id? id[$1, $4]: $4
、2番目のファイルiの最後の列($NF
or)の値を更新します$4
。ない。書類目的地列#1+列#4の一致するキーの組み合わせID配列は見つかった場合は値()を返しid[$1, $4]
、それ以外の場合は現在の値をコピーします。