連続した段落のグループの並べ替え(空行で区切られます)?

連続した段落のグループの並べ替え(空行で区切られます)?

私の考えは今分類にかなり上手になったようです。リスト;しかし、これまでソート方法に関する情報が見つかりませんでした。連続線

次のテキストファイルがあるとしましょう。 (もちろんとても簡単です。)

Echo
Alpha
Delta
Charlie

Golf
Bravo
Hotel
Foxtrot

これで、英数字で行を並べ替えることができますか?各ブロックは別々に?つまり、結果は次のようになります。

Alpha
Charlie
Delta
Echo

Bravo
Foxtrot
Golf
Hotel

sortマニュアルページで見つけた内容によれば、sort組み込みのUNIXコマンドを使用すると、これは不可能かもしれません。または、外部/サードパーティ製のツールを使用せずに実行できますか?

答え1

awk -v RS= -v cmd=sort '{print | cmd; close(cmd); print ""}' file

レコード区切り文字をRS空の文字列に設定すると、awkは一度に段落を段階的に実行します。各段落に対して、段落()をcmd(に設定)に$0パイプし、sort出力を印刷します。に出力段落を区切るために空白行を印刷しますprint ""

Perlの例を挙げると、私はStephaneのアプローチとは異なるアプローチを提案します。

perl -e 'undef $/; print join "\n", sort (split /\n/), "\n" 
    foreach(split(/\n\n/, <>))' < file

完全なSTDINをundef $/使用してインポートできるようにするフィールド区切り記号()を設定解除します。<>その後(段落)にsplit戻ります。 「段落」:改行の周りに行を設定し、再度集めて最後に追加します。\n\nforeachsortsplitsortjoin\n

ただし、これは前の段落にない場合、最後の段落に「末尾の段落」区切り文字を追加する副作用があります。少し美しい方法でこの問題を解決できます。

perl -e 'undef $/; print join "\n", sort (split /\n/) , (\$_ == \$list[-1] ? "" : "\n")
    foreach(@list = split(/\n\n/, <>))' < file

これは段落を割り当て、それが(チェック)の最後の要素である@listことを確認するための「三項演算」を持ちます。 ()の場合は印刷し、そうでない場合は()他のすべての「段落」(の要素)を印刷します。foreach\$_ == \$list[-1]""? ...: ..."\n"@list

答え2

Dravのawk解決策は素晴らしいですが、段落sortごとに1つのコマンドを実行することを意味します。これを防ぐには、次のようにします。

< file awk -v n=0 '!NF{n++};{print n,$0}' | sort -k1n -k2 | cut -d' ' -f2-

または、以下を使用してすべての操作を実行できますperl

perl -ne 'if (/\S/){push@l,$_}else{print sort@l if@l;@l=();print}
          END{print sort @l if @l}' < file

上記の区切り文字は空行ではなく、空行(最初の場合はスペースまたはタブのみを含む行awk、最初の場合は水平または垂直スペース文字)です。perl空の行が本当に必要な場合は、または!NFに置き換えてから置き換えることができます。!length$0==""/\S//./

答え3

私はテキスト段落にsort、shuf、tac、または他のコマンドを使用できるツールをHaskellで書いています。

https://gist.github.com/siers/01306a361c22f2de0122
編集:このツールはこのリポジトリにも含まれています。https://github.com/siers/haskell-import-sort

テキストをチャンクに分割し、\0子チャンクを文字に関連付け、コマンドを介してパイプし、最後に同じ操作を逆にします。

2015年8月28日:私はこのツールを個人的に使用する別の方法を見つけました。 1行の後にN個の段落を選択することです。

paramap grep -aA2 '^reddit usernames' < ~/my-username-file
reddit usernames

foo
bar
baz

a couple
more of these

答え4

TxRLispステップバイステップ:

$ cat data
Echo
Alpha
Delta
Charlie

Golf
Bravo
Hotel
Foxtrot

$ txr -p '(get-lines)' < data
("Echo" "Alpha" "Delta" "Charlie" "" "Golf" "Bravo" "Hotel" "Foxtrot")

$ txr -t '(get-lines)' < data
Echo
Alpha
Delta
Charlie

Golf
Bravo
Hotel
Foxtrot

$ txr -p '(partition* (get-lines) (op where [chain length zerop]))' < data
(("Echo" "Alpha" "Delta" "Charlie") ("Golf" "Bravo" "Hotel" "Foxtrot"))

$ txr -p '[mapcar sort (partition* (get-lines) (op where [chain length zerop]))]' < data
(("Alpha" "Charlie" "Delta" "Echo") ("Bravo" "Foxtrot" "Golf" "Hotel"))

$ txr -p '(interpose (list "") [mapcar sort (partition* (get-lines) (op where [chain length zerop]))])' < data
(("Alpha" "Charlie" "Delta" "Echo") ("") ("Bravo" "Foxtrot" "Golf" "Hotel"))

$ txr -t '(interpose (list "") [mapcar sort (partition* (get-lines) (op where [chain length zerop]))])' < data
Alpha
Charlie
Delta
Echo

Bravo
Foxtrot
Golf
Hotel

引用:行のインポート分割*働くどこチェーン長さゼロフ地図車干渉

関連情報