複数行と列の並べ替え

複数行と列の並べ替え

本文から:

35 EAST 23rd Street           SOUTH AFRICA   5    600   5000000   6 
83 NORTH YELLOWLIGHT AVENUE   SOUTH AFRICA   4    700   7000000   5 
777 NEW AVENUE                SAUDIA         2    900   5000000   3 
FIVE VISA ROAD                MEXICO         3    300    500000   7 
450 JACKSON BLVD              USA            3   1500    300000   4 
25 QUEENS ROAD SOUTH          SOUTH AFRICA   1    900    400000   3

gawkまたは、を使用して南アフリカだけが2番目の列に昇順に出力されるようにするにはどうすればよいですかawksort

私は試した:

awk -F. '/SOUTH AFRICA/ {print }' | sort -n -k5  

しかし、うまくいかないようです。

ベストアンサー1

つまり、最初から一貫性がなく、後でコマンドを実行しようとしたときに問題を引き起こす元の入力を最初に修正する必要があります。

この問題を解決する方法の詳細は次のとおりです。

公開されたコンテンツを確認してください

まず、問題を見てみましょう。たとえば、投稿した内容をコピーして次のように保存する場合original_file.tsv:

35 EAST 23rd Street     SOUTH AFRICA        5   600 5000000     6 
83 NORTH YELLOWLIGHT AVENUE SOUTH AFRICA    4   700 7000000     5 
777 NEW AVENUE  SAUDIA      2   900 5000000     3 
FIVE VISA ROAD      MEXICO      3   300 500000      7 
450 JACKSON BLVD        USA     3   1500    300000      4 
25 QUEENS ROAD SOUTH        SOUTH AFRICA        1   900 400000      3

一見するとすっきりと大丈夫そうです。残念ながら、次のように詳しく見てみると、cat -Aコマンドプロンプトに次の内容が表示されます。

$ cat -A original_file.tsv
35 EAST 23rd Street^I^ISOUTH AFRICA^I^I5^I600^I5000000^I^I6 $
83 NORTH YELLOWLIGHT AVENUE^ISOUTH AFRICA^I4^I700^I7000000^I^I5 $
777 NEW AVENUE^ISAUDIA^I^I2^I900^I5000000^I^I3 $
FIVE VISA ROAD^I^IMEXICO^I^I3^I300^I500000^I^I7 $
450 JACKSON BLVD^I^IUSA^I^I3^I1500^I300000^I^I4 $
25 QUEENS ROAD SOUTH^I^ISOUTH AFRICA^I^I1^I900^I400000^I^I3$
  • ^I「ここにタブがあります」という意味
  • $「これが行の終わりだ」という意味

これにより、次の不一致がすぐに明らかになります。

  • 行1:35 EAST 23rd StreetタブタブSOUTH AFRICA...
  • 行2:83 NORTH YELLOWLIGHT AVENUEタブSOUTH AFRICA...

1行にはフィールド1とフィールド2を区切る2つのタブがあり、次の行には1つのタブしかありません。行ごとに異なります。

sortただし、各行が異なる場合、各行の区切り記号または区切り文字が一貫していないように配置されている場合は、ここからデータを正しく取得する方法はありません。

クリーンバージョン

(少なくともこの例では)唯一の問題はダブルタブが表示されているようですが、実際には単一のタブである必要があります。したがって、可能であれば、手動編集の代わりにツールを使用してクリーンアップする必要があります。ここではsedこれをクリーンアップして結果をファイルに保存できます。たとえば、resultsを呼び出すことができますclean_file.tsv

$ sed 's/\t\t/\t/g;s/ $//g' original_file.tsv  > clean_file.tsv
  • s/\t\t/\t/g2つのタブを検索して1つに置き換える
  • ;sedパラメーターで複数のコマンドを区切ります。
  • s/ $//g一部の行末に空白があるようで、ここでは削除します。
  • >ファイルリダイレクトはsed出力をファイルに保存します。clean_file.tsv

clean_file.tsv良い:

35 EAST 23rd Street SOUTH AFRICA    5   600 5000000 6
83 NORTH YELLOWLIGHT AVENUE SOUTH AFRICA    4   700 7000000 5
777 NEW AVENUE  SAUDIA  2   900 5000000 3
FIVE VISA ROAD  MEXICO  3   300 500000  7
450 JACKSON BLVD    USA 3   1500    300000  4
25 QUEENS ROAD SOUTH    SOUTH AFRICA    1   900 400000  3

再利用できますが、cat -A今は次から利用できますclean_file.tsv

35 EAST 23rd Street^ISOUTH AFRICA^I5^I600^I5000000^I6$
83 NORTH YELLOWLIGHT AVENUE^ISOUTH AFRICA^I4^I700^I7000000^I5$
777 NEW AVENUE^ISAUDIA^I2^I900^I5000000^I3$
FIVE VISA ROAD^IMEXICO^I3^I300^I500000^I7$
450 JACKSON BLVD^IUSA^I3^I1500^I300000^I4$
25 QUEENS ROAD SOUTH^ISOUTH AFRICA^I1^I900^I400000^I3$

これで、すべてが一貫していることがわかります。慎重に計算すると、各行にはフィールド区切り文字またはフィールド区切り文字と同じ数のフィールド(ここでは6つ)と同じ数のタブ(ここでは5つ)があります。

ああ、並べ替え

これでclean_file.tsv入力形式が正しく指定されたので、コマンドを実行して次のことを確認できます。

$ awk '/SOUTH AFRICA/ {print }' clean_file.tsv | sort -t $'\t' -k5,5n
25 QUEENS ROAD SOUTH    SOUTH AFRICA    1       900     400000  3
35 EAST 23rd Street     SOUTH AFRICA    5       600     5000000 6
83 NORTH YELLOWLIGHT AVENUE     SOUTH AFRICA    4       700     7000000 5
  • -Fフィールド操作は実行されないため、ここでは不要で、一致する行を印刷するためにのみ使用される-Fフィールド区切り文字を指定するために使用されたため、元のコマンドと比較して削除されました。awkSOUTH AFRICA
  • -t $'\t'フィールド区切り記号をタブとして指定します。
  • -k5,5この場合、最後から2番目の列が必要です。ここで、列5はこの6つの列データサンプルの最後から2番目の列であるため、列5から列5にソートします。
  • n数値の順序を示します。デフォルトは昇順であるため、これ以上指定する必要はありません。

したがって、生データをクリーンアップしてこのawk合計を実行すると、アイテムを見つけsortSOUTH AFRICA5番目のフィールドに基づいて昇順に並べ替えることができます。

おすすめ記事