ファイル A の内容を変更せずに、ファイル A の列 3 に基づいてファイル B を並べ替える

ファイル A の内容を変更せずに、ファイル A の列 3 に基づいてファイル B を並べ替える

次のファイルがあります:

cat fileA.txt

seattle    1991  west
atlanta    1993  west
turlock    1998  west
marysville 2004  south
newyork    2007  north
canada     2004  west

2 番目のファイルは次のようになります。

cat fileB.txt

popular
someWhatPopular
boring
popular
popular
popular

次のような出力を取得したいと思いますfileB.txt:

popular popular popular someWhatPopular boring popular

つまり、私は3列fileB.txt目に並べ替えようとしているのですfileA.txt

次のコードを試しました:

   #!/bin/bash
   sort -s -k3,3 fileA.txt fileB.txt

しかし、うまくいきませんでした。何か提案はありますか? ハードコーディングを必要としないものなら何でも結構です。Bash/awk/sed など。

答え1

これは Linux の問題というよりも、データ構造の問題です。リンクするには、両方のテーブルに共通のエントリ (キー) が必要です。これは、他の「データベース」の場合と同じです。また、データ テーブルの最初の列に一意のキーを保持しておくことをお勧めします。そうすれば、好きなだけ並べ替えやリンクを行うことができます。

@glennjackman マッピングのようなものを例にとると、マッピングキーを北、南などとして定義します。

1 south somewhatPopular
2 west popular
3 north boring
4 east unexplored

ファイル というファイルpopularityfileA一意のキーを含めるように修正する

1 seattle    1991  west
2 atlanta    1993  west
3 turlock    1998  west
4 marysville 2004  south
5 newyork    2007  north
6 canada     2004  west

次に、選択したキーでこれらのファイルを操作できますjoin(この場合、の列2はのpopularity列4にマップされますfileA)。ただし、join 両方のファイルをキーフィールドでソートする必要があります。

join -1 4 -2 2 <(sort -k4 fileA) <(sort -k2 popularity) | sort -k2 | awk '{print $6}'

popular
popular
popular
somewhatPopular
boring
popular

少し強引なアプローチですが、最大限の柔軟性が得られます。

上記のコマンドを各パイプで分割すると、各ステップで何が行われるかがわかります。

編集:説明join -1 4 -2 2 # its in the man pages

これは、join表 1 の 4 列目 (-1 4) を見て、表 2 の 2 列目 (-2 2) で一致する値を見つけるように指示します。

join次に、2つのテーブルの列を1つのテーブルにまとめますが、キー列(北など)は1つだけ含めます。

join -1 4 -2 2 <(sort -k4 fileA) <(sort -k2 popularity)

そしてそれはより明確になるはずだ

動作させるためにデータテーブルを並べ替える必要があったためjoin

| sort -k2

結合されたテーブルを元の順序に戻します。

必要な列は結合された表の6列目なので、

| awk '{print $6}'

stdout に出力します。

答え2

paste2 つの「テーブル」ファイルを一緒にして、出力を にパイプしsortcut4 番目の列のみを保持してみることもできます。

未テストの(現時点では携帯電話での)試みは次のようになります

paste fileA fileB | sort -s -k3,3 | cut -f4

答え3

アルファベット順のマッピングは以下で取得できます。

paste <(awk '{print $NF}' fileA.txt | sort -u) <(sort -u fileB.txt)
north   boring
south   popular
west    someWhatPopular

そして、awk を使用して、希望する出力形式を生成できます。

awk '
    NR==FNR {map[$1] = $2; next} 
    {print map[$NF]}
' <(paste <(awk '{print $NF}' fileA.txt | sort -u) <(sort -u fileB.txt)) fileA.txt
someWhatPopular
someWhatPopular
someWhatPopular
popular
boring
someWhatPopular

関連情報