11

sed や cat などの bash コマンドのみを使用して、一部のテキスト ブロックの順序を元に戻すにはどうすればよいですか? 私が欲しいのは tac のようなものですが、行ごとに操作するのではなく、ブロックごとに操作します。例:

から

/Section 3/
Rabbits
Dogs
Cats

/Section 2/
Eagles
Mice

/Section 1/
Dogs
Rabbits
Lemmings

/Section 1/
Dogs
Rabbits
Lemmings

/Section 2/
Eagles
Mice

/Section 3/
Rabbits
Dogs
Cats

一部のファイルでは、上記の例のように、ブロックの先頭がスラッシュでマークされています。他の例では、ブロックはブロック間に 1 つ以上の空白行が存在することによってのみマークされます。

4

4 に答える 4

4

では、次のコマンドemacsを使用できます。sort-paragraphs

Ctrl-xhMeta-xsort-paragraphsEnter


vim: https://superuser.com/questions/365094/sort-file-per-paragraph-in-vim _


基本的な UNIX ツールを使用します。

awk -F'\n' -vRS='' -vOFS=',' '{$1=$1}1' input.txt |
    sort |
        tr ',' '\n' |
            sed 's@^/@\n/@'

を使用awkしてデータを に変換しcsv、次にsortcsv変換し、最後にcsvリスト スタイルに戻します。


結果:

/Section 1/
Dogs
Rabbits
Lemmings

/Section 2/
Eagles
Mice

/Section 3/
Rabbits
Dogs
Cats

編集:申し訳ありませんが、あなたの質問を注意深く見ていませんでした。sortコマンドをに変更してtac、順序を逆にすることができます。

于 2012-06-03T23:13:31.000 に答える
3

すべてのブロックを区切る空白行がある場合、

awk 'BEGIN{ORS=RS RS;RS=""}{a[NR]=$0}END{for(i=NR;i>0;i--)print a[i]}'
于 2012-06-04T00:39:45.930 に答える
1

あなたの例でブロックを区切るものは何ですか? 2 つの改行。Emacs Lisp では、テキストが文字列の場合、 と をインストールするdashs、次の 2 つの同等の式のいずれかを使用できます。

(s-join "\n\n" (nreverse (s-split "\n\n" s))) ; where s is your string
(->> s (s-split "\n\n") nreverse (s-join "\n\n"))

->>s連続する関数呼び出しをプルするダッシュのスレッド化マクロです。*nix パイプを考えてみましょう: s | s-split "\n\n" | nreverse | s-join "\n\n".

ファイルを開き、ブロックを反転してから同じファイルに保存する Emacs Lisp 関数が必要な場合は、fファイル操作ライブラリをインストールすることもできます。

(defun reverse-blocks (f)
  "F is a filename."
  (interactive "fFind file: ") ; letter `f` is filename goes in first arg
  (let ((s (f-read f))) ; read file into a string
    (--> s
         s-chomp ; remove trailing newline
         (s-split "\n\n" it)
         nreverse
         (s-join "\n\n" it)
         (f-write it 'utf-8 f)))) ; write to the same file

ここでは、別の後続マクロを使用-->します。これにより、前の計算の結果を次の計算の引数に入れることができますit。たとえば、 の結果が でnreverseあるX場合、同等のものは になります(s-join "\n\n" X)。最後に、逆にするだけでなく、「Section」という単語の後の数字に基づいてブロックを並べ替えたいとします。

(--sort (< (string-to-number (cadr (s-match "/.*?\\([0-9]\\)/" it)))
           (string-to-number (cadr (s-match "/.*?\\([0-9]\\)/" other))))
        it) ; put it instead of nreverse

これを使用dash-functionalすると、次と同等になります。

(--sort (-on '<
             (-compose 'string-to-number
                       'cadr
                       (-partial 's-match "/.*?\\([0-9]+\\)/")))
        it) ; put it instead of nreverse

ドキュメントを読んで、dash何をするのかを理解してください。-on-compose-partial

于 2015-02-18T20:14:43.260 に答える
1

csplitそれらを別々のファイルに分割し、生成されたファイル名を別のファイルに入れ、次にtacファイル名をマージするために使用します。

于 2012-06-03T23:14:20.657 に答える