ファイルの各行の後半を別のファイルの対応する部分に置き換えます。

ファイルの各行の後半を別のファイルの対応する部分に置き換えます。

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

純粋にbashbashシェルなら、組み込みのシェルだけを使ってこれを行うことができ、外部ユーティリティ/コマンドは必要ありません...しかし、場合によっては専用のテキスト処理ツールよりも遅くなることがあります。少し、それにもかかわらず、知ることは役立ちます。

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

関連情報