web-dev-qa-db-ja.com

sortコマンドを使用した列出力の反転

シェルスクリプトのパラメーターとして指定されたファイルからすべての単語を並べ替える必要があります。ワンライナーは次のとおりです。

tr  [:space:] '\n' <$1  | sort -nrk2,2 | uniq -c |sed 's/^ \+//g'

基本的に、ファイルに次のようなものがある場合:

bla bla bla bla hu hu hu

出力されます

4 bla
3 hu

私はそれらが次のようなものになりたい

bla 4
hu 3
2
gigiman

sedコマンドを、フィールドの順序を入れ替える簡単なawkコマンドに置き換えることができます

... | awk '{print $2,$1}'
4
steeldriver

これを行うには多くの方法があります。 Steeldriverはすでに古典的なawkアプローチを提供しました。他の選択肢は次のとおりです。

  1. sedを使用して、非空白(\S)文字の2つのグループをキャプチャし、それらを切り替えます。

    ... | sed -E 's/\s*(\S+)\s+(\S+)/\2 \1/'
    
  2. Perlを使用します。 -aスイッチにより、awkのように機能します。空白の各入力行を自動的に分割し、各フィールドを配列@Fの要素として保存します。したがって、1番目のフィールドは$F[0]、2番目の$F[1]などになります。

    ... | Perl -lane 'print "$F[1] $F[0]"'
    
  3. すべてにPerlを使用します。

    Perl -lane '$k{$_}++ for @F; }{ print "$_ $k{$_}" for keys(%k)' "$1"
    

    ここで、Perlは入力ファイルを1行ずつ読み取り、各行にスクリプトを適用します。 $k{$_}++ for @Fは、各Word(@Fの各フィールド)をハッシュ%kのキーとして保存し、Wordが表示されるたびに関連する値を1ずつ増やします。次に、ファイルが処理された後(}{の意味)、Word($_)と各キーの表示回数($k{$_})を出力しますハッシュに保存されます。

  4. すべてにawkを使用します。

    awk '{for(i=1;i<=NF;i++){a[$i]++}}END{for(i in a){print i,a[i]}}' "$1"
    

    最初のforループは各フィールドを繰り返し、配列aのそのフィールドに関連付けられた値に1を追加します。次に、ファイルの最後で、aの各要素をループし、要素(Word)と関連する値(Wordが表示された回数)を出力します。

  5. 元のパイプラインでシェルを使用します。

    ... | while read a b; do echo "$b $a"; done
    
6
terdon