Text-Processing

搜尋、插入、移動和插入

  • November 18, 2016

我想在文件中搜尋模式的每條記錄(記錄由空行定義)NAME#AAAA。如果匹配,則#在記錄行的前面插入一個AGE並將該行移動到段落的頂部。然後在最後插入一行AGE NIL

輸入文件:

NAME#AAAA
STD 1
SEC A
AGE 5

NAME#BBBB
STD 2
SEC B
AGE 6


NAME#CCCC
STD 3
SEC C
AGE 7

NAME#AAAA
STD 4
AGE 9


NAME#AAAA
STD 7
SEC A
AGE 12

預期輸出

#AGE 5
NAME#AAAA
STD 1
SEC A
AGE NIL

NAME#BBBB
STD 2
SEC B
AGE 6

NAME#CCCC
STD 3
SEC C
AGE 7

#AGE 9
NAME#AAAA
STD 4
AGE NIL

#AGE 12
NAME#AAAA
STD 7
SEC A
AGE NIL

另外,我需要它的倒數。只是為了恢復所做的更改。請注意,我在 AIX 機器上執行所有這些操作。

ex這是POSIX 指定的文件編輯首選工具的完美案例。

(順便說一句,如果您曾經使用過vi,那麼您可能很熟悉,ex因為您輸入的vi以冒號開頭的所有內容:都是ex命令。 ex是 的前身vi。)

printf %s\\n 'g/NAME#AAAA/ /AGE/t- | s/^/#/ | /AGE/s/.*/AGE NIL/' x | ex input.txt

如果您想在實際保存文件之前對其進行測試,x請將管道符號之前的final更改為%p,修改後的文件不會保存,但修改後的版本將列印為stdout. 所以這裡是測試命令:

printf %s\\n 'g/NAME#AAAA/ /AGE/t- | s/^/#/ | /AGE/s/.*/AGE NIL/' %p | ex input.txt

解釋:

printf %s\\n提供了一種簡單的方法來提供多個命令,ex每個命令後面都有一個換行符。

g/regex/是全域命令;它在與給定正則表達式匹配的每一行上執行後面的命令(直到下一個換行符)。

/AGE/t-將與模式匹配的下一行複製到目前行(即該行)/AGE/之前的位置。NAME#AAAA它還將游標移動到該行的新副本(因此現在成為“目前行”)。

|是 中的命令分隔符ex

s/^/#/在複製的AGE行前加上井號標籤。(或井號,取決於您的方言。);)

下一條命令實際上有兩部分:/AGE/是地址,它使該命令對包含該模式的下一行進行操作,並將s/.*/AGE NIL/該行替換為AGE NIL.

x保存對文件的更改並退出。


扭轉變化

為了扭轉這些變化,我會做以下事情:

printf %s\\n 'g/NAME#AAAA/ ?^#AGE? m /^AGE/ | s/^#// | -d' %p | ex input.txt

然後在驗證更改後,實際保存更改:

printf %s\\n 'g/NAME#AAAA/ ?^#AGE? m /^AGE/ | s/^#// | -d' x | ex input.txt

解釋:

全域命令和以前一樣。

#AGE從 NAME 行之前開始的行,將其移到以 . 開頭的下一行之後AGE

去掉前導#

刪除前一行-d(即 NIL 年齡行)。

列印或保存更改。

引用自:https://unix.stackexchange.com/questions/277590