A、B 2つのファイルがあります。両方のファイルの各行はエントリと見なされます。各項目の形式は固定されており、スペースで区切られたキーと説明で構成されています。次の例に示すように。
UASCH-XCF02-SP062 /users/documents/ark
最初の部分UASCH-XCF02-SP062
がポイントで、最後の部分が/users/documents/ark
説明です。ファイルAとBにはそれぞれ1000個と100000個のエントリがあります。同じファイルの各キーは一意ですが、ファイルAのエントリのキーはファイルBにも表示されますが、説明は異なります。次の簡単な例で見ることができます。
ファイルA
UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
文書B
UASCH-XCF02-SP062 /users/documents/ark3
UASCH-XXF02-SP063 /users/documents/ark4
UASCH-XXF03-SP064 /users/documents/ark5
ファイルBの同じキーに対応する説明をファイルAのキーに対応する説明に置き換えたい。例の結果は次のとおりです。
文書B
UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
UASCH-XXF03-SP064 /users/documents/ark5
この目標を達成する方法は?
答え1
これはAWKを使用して行うことができます。
$ awk 'NR==FNR{a[$1]=$2;next} $1 in a {$2=a[$1]} 1' A.txt B.txt
UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
UASCH-XXF03-SP064 /users/documents/ark5
編集:Edのコメントにより、AWK式の後半を簡素化しました。
ファイルBを編集するには、AWK出力を一時ファイルにリダイレクトし、ファイルBをそのファイルに置き換えます。
awk 'NR==FNR{a[$1]=$2;next} $1 in a {$2=a[$1]} 1' A.txt B.txt >B.txt.tmp
mv B.txt.tmp B.tmp
仕組み。まずNR==FNR
、最初のファイルと2番目のファイルを区別するイディオムを使用して、最初のファイル(A)のすべてのキーと値のペアを連想配列に保存します。次に、2番目のファイル(B)を繰り返すときに現在のキーが最初のファイルにあることを確認し、そうである場合は、現在の値を最初のファイルで見つかった値に置き換えます。
答え2
純粋にbash
…bash
シェルなら、組み込みのシェルだけを使ってこれを行うことができ、外部ユーティリティ/コマンドは必要ありません...しかし、場合によっては専用のテキスト処理ツールよりも遅くなることがあります。少し、それにもかかわらず、知ることは役立ちます。
array
次のように連想配列を宣言します。
declare -A array
A
次に、スペース、つまり次の内部フィールド区切り文字を使用してファイルを読み取ります。
while IFS=' ' read -r k v
do
array[$k]="$v"
done < A
次に、ファイルB
行を読み取り、キーを比較し、値を変更し、最終結果を次のように印刷します。
while IFS=' ' read -r k v
do
if [[ "${!array[*]}" =~ "$k" ]]
then
printf '%s %s\n' "$k" "${array[$k]}"
else
printf '%s %s\n' "$k" "$v"
fi
done < B
すると、以下が出力されます。
UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
UASCH-XXF03-SP064 /users/documents/ark5
気づく:のようにバッシュ配列一次元的なので、上記のアプローチはユースケースに適しています(つまり一つ鍵と一つ値)に似ていますが、各追加値を別々のトークンに解析する必要がある場合、複数の値を持つキーには機能しません。
答え3
ソートは固定されており、「uniq」は最初のN文字のみを考慮することができるので...
猫AB |ソートuniq -w 17> /tmp/foo;
はい - 期待どおりに動作します
$ cat A B | sort | uniq -w 17
UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
UASCH-XXF03-SP064 /users/documents/ark5