Text-Processing

是否可以將另一個字元串之後以 # 開頭的字元串移動到前一行?

  • November 10, 2021

我有一個看起來像這樣的腳本文件:

auditctl -a always,exit -F arch=b64 -S openat -F auid=1000      <TAB> #description of command....
auditctl -a ....                                                <TAB> #long description

(注意註釋前的 TAB 字元。)

可以使用sed, 或awk, 或vim內部命令將描述放在#字元串本身的上方,因此我將獲得如下內容:

#description of command....
auditctl -a always,exit -F arch=b64 -S openat -F auid=1000      


#long description
auditctl -a ....

我試過這個norm命令,但結果是一場災難

:'<,'>norm f#D O P

使用sed,可以使用反向引用來匹配模式:

sed 's/\(PATTERN1\)\(PATTERN2\)/\2\n\1/'

將反轉兩種模式並在其間添加換行符。PATTERN1 將是例如^.*,即從行首開始的任何字元,PATTERN2#.*$即是一個雜湊符號,後跟任意數量的字元,直到行尾。

要刪除多餘的空格,可能需要添加以下內容:

's/ *$//'

最好也#通過在第一部分的匹配中排除字元來處理自己文本中的註釋 via [^#],即任何不是的字元#。結合起來,它可以:

sed 's/\(^[^#]*\)\(#.*$\)/\2\n\1/;s/ *$//'

使用 GNU awk 作為第三個參數match()\S/\s速記:

$ awk 'match($0,/([^#]*\S)\s*(#.*)/,a) { $0=a[2] ORS a[1] } 1' file
#description of command....
auditctl -a always,exit -F arch=b64 -S openat -F auid=1000
#long description
auditctl -a ....

或使用任何 POSIX awk:

$ awk 'match($0,/[[:space:]]*#/) { $0=substr($0,RSTART+RLENGTH-1) ORS substr($0,1,RSTART-1) } 1' file
#description of # command....
auditctl -a always,exit -F arch=b64 -S openat -F auid=1000
#long description
auditctl -a ....

請注意,無論註釋包含哪些字元(包括 a #,以及註釋前是否有空格),上述操作都將起作用,並且在列印之前,它將從行的其餘部分的末尾去除任何註釋前的空格。

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