簡體   English   中英

如何逆轉文本塊的順序

[英]How to reverse order of blocks of text

如何僅使用像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

在某些文件中,塊的開頭用斜杠標記,如上例所示。 在其他情況下,塊僅通過它們之間存在一個或多個空行來標記。

emacs ,您可以使用sort-paragraphs命令:

Ctrl-x h Meta-x sort-paragraph 回車


vimhttps//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以反轉順序。

如果有空白行分隔所有塊,

awk 'BEGIN{ORS=RS RS;RS=""}{a[NR]=$0}END{for(i=NR;i>0;i--)print a[i]}'

使用csplit將它們拆分為單獨的文件,將生成的文件名放入另一個文件中,然后使用tac獲取要合並的文件名。

你的例子中的塊分開了什么? 2個換行符。 在Emacs Lisp中,如果文本是字符串,如果安裝了dashs ,則可以使用以下兩個等效表達式之一:

(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" s | s-split "\\n\\n" | nreverse | s-join "\\n\\n" 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做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM