シェルスクリプトのソート

シェルスクリプトのソート

小さなファイルを並べ替えようとしていますが、一部の項目には2つの単語が含まれていますが、1つの項目に並べ替えたいと思います。

たとえば、次のような小さなリストを考えてみましょう。

 peter barker painter
 carl baker cook
 joshua carpenter

名前と職業です。それでは、 sort を使ってこれらの項目をソートしたいとしましょう。

問題は、 sort がスペースをフィールドとして使用することです。したがって、 sort -k 1n を使用すると、名前でソートされます。

しかし、フルネームに基づいてソートし、オプションでジョブに基づいてソートしたいと思います。ご覧のとおり、一部のアンサンブルには名前がありませんが、Joshuaには名前と職業しかありません。したがって、その人の場合、私は名前順に並べ替えたいのですが、他の人の名前はすべて名前順に並べ替えたいと思います。

これは達成できますか?

ベストアンサー1

姓だけが欠落している(名前を除く)、ファイルの単語にスペースが含まれていないとします。極度に難易度)まず、データをタブ区切り形式に変換し、欠落している姓を空のフィールドに置き換えます。

$ awk -v OFS='\t' 'NF == 3 { $1 = $1 } NF == 2 { $3 = $2; $2 = "" } { print }' <file
peter   barker  painter
carl    baker   cook
joshua          carpenter

スクリプトawkは、2つまたは3つのフィールドを含む行を検出します。すでに3つのフィールドを持つ行をタブで区切られた3つのフィールドに再フォーマットしますが、元の2つのフィールドのみを含む行の2番目のフィールドを3番目のフィールドに移動します。

次に、タブを区切り文字として使用してデータをソートします。

$ awk -v OFS='\t' 'NF == 3 { $1 = $1 } NF == 2 { $3 = $2; $2 = "" } { print }' <file | sort -t $'\t' -k1,2 -k3
carl    baker   cook
joshua          carpenter
peter   barker  painter

ここでは、名前(フィールド1とフィールド2)に基づいて並べ替え、ジョブに基づいて並べ替えます。bashタブなどのシェルを使用しているとします$'\t'


タブ文字(ここでは:)をデータを邪魔しない他の文字に置き換えることができます。

$ awk -v OFS=':' 'NF == 3 { $1 = $1 } NF == 2 { $3 = $2; $2 = "" } { print }' <file | sort -t ':' -k1,2 -k3
carl:baker:cook
joshua::carpenter
peter:barker:painter

trその後、結果を渡して選択した区切り記号(ここでは表示に適しているため、タブに置き換えます)を置き換えます。

$ awk -v OFS=':' 'NF == 3 { $1 = $1 } NF == 2 { $3 = $2; $2 = "" } { print }' <file | sort -t ':' -k1,2 -k3 | tr ':' '\t'
carl    baker   cook
joshua          carpenter
peter   barker  painter

おすすめ記事