我正在嘗試替換檔案行之間的模式。
具體來說,我想,\n &用 , &\n 大檔案和多個檔案替換。這實際上將符號 & 移動到上一行。使用 CTR H 很容易,但我發現使用 sed 很難。
因此,初始檔案采用以下形式:
A ,
& B -,
& C ),
& D ,
& E (,
& F *,
# & G -,
& H ,
& I (,
& J ,
K ?,
輸出所需的形式是:
A , &
B -, &
C ), &
D , &
E (, &
F *, &
# & G -,
H , &
I (, &
J ,
K ?,
按照之前關于 stackoverflow 的回答問題,我嘗試使用以下命令對其進行轉換:
sed ':a;N;$!ba;s/,\n &/&\n /g' file1.txt > file2.txt
sed -i -e '$!N;/&/b1' -e 'P;D' -e:1 -e 's/\n[[:space:]]*/ /' file2.txt
但如果檔案中存在符號“#”,它們就會失敗。
有什么方法可以更簡單地替換匹配的模式,比如說:
sed -i 's/,\n &/, &\n /g' file
先感謝您!
uj5u.com熱心網友回復:
使用sed
$ sed ':a;N;s/\n \ \(&\) \(.*\)/ \1\n \2/;ba' input_file
A , &
B -, &
C ), &
D , &
E (, &
F *,
# & G -, &
H , &
I (, &
J ,
uj5u.com熱心網友回復:
如果您使用 GNUsed并且您的檔案不包含 NUL 字符(ASCII 代碼 0),您可以使用其選項將整個檔案作為單個字串處理,以及替代命令(標志)-z的多行模式。m該m標志不是絕對需要的,但它簡化了一點(.并且字符類不匹配換行符):
$ sed -Ez ':a;s/((\`|\n)[^#]*,)((\n.*#.*)*)(\n[[:blank:]]*)&/\1 \&\3\5 /gm;ta' file
A , &
B -, &
C ), &
D , &
E (, &
F *, &
# & G -,
H , &
I (, &
J ,
K ?,
這對應于您的文本規范和您展示的示例所需的輸出。但這有點復雜。它不是處理以換行符結尾的行,而是處理以換行符(或檔案開頭)開頭并在下一個換行符之前結束的子字串。讓我們將這些“塊”命名為。
我們搜索以下形式的塊序列AB*C:
A是一個不包含#. 它通過(\<backtick>|\n)[^#]*,which 表示檔案開頭或換行符匹配,后跟除換行符和之外的任意數量的字符#,后跟逗號。B*是包含 . 的任意數量(包括無)的塊#。它的匹配\n.*#.*方式是換行符,后跟除換行符外的任意數量的字符,后跟除換行符之外的#任意數量的字符。C是一個以換行符開頭的塊,后跟空格和&. 它通過\n[[:blank:]]*&which 表示換行符,后跟任意數量的空格和一個&.
如果我們找到這樣一個序列,我們在 的末尾AB*C添加一個空格和 a ,我們不會更改,而是將第一個替換為空格。我們重復,直到找不到這樣的序列。&AB*&C
注意:如果逗號后面可以跟在換行符之前的空格,我們必須將它們考慮在內。如果你想保留它們:
$ sed -Ez ':a;s/((\`|\n)[^#]*,[[:blank:]]*)((\n.*#.*)*)(\n[[:blank:]]*)&/\1 \&\3\5 /gm;ta' file
別的:
$ sed -Ez ':a;s/((\`|\n)[^#]*,)[[:blank:]]*((\n.*#.*)*)(\n[[:blank:]]*)&/\1 \&\3\5 /gm;ta' file
uj5u.com熱心網友回復:
假設這條線
# & G -,
&是一個注釋行,稍后可能會取消注釋,在此行中處理也可能是有意義的。不知道資料的用途,這可能有用也可能沒用。
使用GNU awk,命令
awk 'BEGIN { RS=ORS="," } { print gensub(/(\n[ \t#]*)&/, " \\&\\1 ",1) }' inputfile
將輸入
A ,
& B -,
& C ),
& D ,
& E (,
& F *,
# & G -,
& H ,
& I (,
& J ,
K ?,
進入
A , &
B -, &
C ), &
D , &
E (, &
F *, &
# G -, &
H , &
I (, &
J ,
K ?,
解釋:
RS=ORS=","將逗號設定為記錄分隔符而不是換行符。gensubGNU 特定的替換函式,它允許反向參考匹配的組。/(\n[ \t#]*)&/搜索模式:括號定義了一個組 (1),它由一個換行符\n后跟任何空格、制表符或注釋字符序列組成[ \t#]*。該組后面跟著一個&字符。" \\&\\1 "替換:空格后跟&,然后是捕獲的組 (1) (\\1) 和一個額外的空格來替換洗掉的&。(\\&獲取文字&字符而不是插入整個匹配項是必要的。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/473077.html
