一致する文字を使用した2つのファイルのマージ

一致する文字を使用した2つのファイルのマージ
File1:
X
X
P
X
N
X
Q
File2:
P 1
N 5
Q 0

Desired output:
X 0
X 0 
P 1
X 0
N 5
X 0
Q 0

私はbashでmergeコマンドを使用するためにいくつかの方法を試しました。私はそれを動作させることはできません。

答え1

Awkとても簡単にできます!

awk 'FNR==NR{ hash[$1]=$2; next}{ if ($0 in hash) $2 = hash[$1]; else  $2 = "0" }1' file2 file1

Awk入力ラインを処理して動作します。一つ一度。ファイル処理の前後に実行するタスクをAwk提供しBEGIN{}、含む特別な句もあります。END{}ファイル内の各行はFS特殊変数(デフォルトでは1つ以上の空白)値に基づいて分割され、これらの個々のフィールド$1には..から$2アクセスできます。$NF

したがって、このセクションは結合されたファイルと現在のファイルの行番号を追跡するため、FNR==NRコマンドに指定された最初のファイル引数を処理するように設計されています。したがって、最初のファイルの各値に対して、その値はという配列にハッシュされ、FNRNR$1hashファイル処理が発生すると、このセクションでは$0 in hashその行をハッシュインデックス位置にマッピングします。そのようなマッピングされた行の場合はその行を印刷し、マッピングされていない行の場合は印刷します。file1file20

これは、個々のフィールドまたは上記の特殊変数に対する変更に基づいて行全体をデフォルトで再構築/印刷する{..}1簡単な表現です。{..; print}

もっと見るawkの組み込み変数の制御

答え2

を使用してこれを行うことができますが、sed正規表現Gnuをあまり複雑にしないエディタバージョンがあります。

基本的なアイデアは、まずFile2を読み、改行で区切られた予約済みスペースに保存することです。

次に、File1 を読み込み、File2 の行を読み取ったばかりの File1 行に追加します。スケジュールされたスペースでFile1行の存在を検出できる場合は、他のコンテンツのパターンスペースを切り取ってFile2行をそのまま印刷できます。

それ以外の場合は、File1行を印刷して0を追加します。

$ sed -Ee '
    / /{H;d;}
    G
    s/^(\S+)\n.*\n(\1 \S+)(\n.*)?$/\2/;t
    s/\n.*/ 0/
' File2 File1

関連情報