如何在模式前插入反斜線和換行符?

如何在模式前插入反斜線和換行符?

我想捕獲變數中的 \n (假設 a)並替換文件中搜尋模式前面的 $a (abc.txt)

有人可以建議我解決方案嗎?

> cat abc.txt
hi how are you how is your health
> echo $a
\

預期輸出(搜尋模式 - how

hi \
how are you \
how is your health

答案1

在類似 Bourne 或類似 rc 的 shell 中

a='
' perl -pe 's/pattern/$ENV{a}$&/g' < abc.txt

將傳遞一個包含換行符a的環境變量,並在 的內容中每次出現 之前插入該變量的內容。perlperlpatternabc.txt

要在類似 Bourne 的 shell 中將變數x以外的任何字元指派給任何字符,您可以使用:'

a='x'

所以對於反斜線:

a='\'

對於換行符:

a='
'

對於像換行符這樣的控製字符,但是對於退格鍵或回車符來說情況會更糟,這會使代碼不太清晰。

ksh93 引入了一種新$'...'形式的引號來以轉義形式指定這些字元。其他 shell,如bashzshmkshFreeBSDsh已經複製並擴展了它(如$'\uXXXX'由 新增的形式zsh)。

在這些 shell 中,您可以使用:

a=$'\n' a=$'\b' a=$'\r' a=$'\\' a=$'\''

指定換行符、退格符、回車符、反斜線或單引號字元。

該引用運算子還不是標準的,因此您不能在可移植sh腳本中使用它。標準替代方案是使用:

a=$(printf '\b')

例如,對於退格鍵,但這不適用於換行符,因為命令替換 ( $(cmd)) 會從 的輸出中刪除尾隨換行符cmd。人們必須求助於以下駭客:

nl=$(printf '\n.'); nl=${nl%.}

(即添加一個.然後刪除它)以保留它。

請注意,它perl也理解\n其程式碼中的這些符號,因此您可以執行以下操作:

perl -pe 's/pattern/\n$&/g' < abc.txt

GNU 實作sed(以及現在的其他一些實作)也支持它:

sed 's/pattern/\n&/g' < abc.txt

但這不是標準的。標準情況下,s命令 in的替換部分中的換行符號sed必須用反斜線後跟實際的換行符號來表示,因此將是:

backslash='\' newline='
'
sed "s/pattern/$backslash$newline&/g" < abc.txt

或沒有變數:

sed 's/pattern/\
&/g' < abc.txt

因此,如果您想在 前面同時插入反斜線和換行符pattern,您需要:

sed 's/pattern/\\\
&/g' < abc.txt

總共 3 個反斜杠,兩個用於字面反斜杠,一個用於換行。或與perl

perl -pe 's/pattern/\\\n$&/g' < abc.txt

或用你的a變數:

a='\
' perl -pe 's/pattern/$ENV{a}$&/g' < abc.txt

答案2

您也可以使用自己的 bash 命令:

cat abc.txt | sed -e 's/how/\nhow/g' |  while read line; do echo "$line \\"; done

相關內容