如何使用 sed 寫入儲存在變數中的檔案名稱?

如何使用 sed 寫入儲存在變數中的檔案名稱?

bash腳本中,如何sed寫入檔案名稱儲存在 bash 變數中的檔案?輸出重定向不起作用,因為我想就地編輯一個文件,將與正規表示式匹配的行拉到另一個文件中,然後在第一個文件中刪除它們。

就像是:

sed -i '/^my regex here$/{;w file2;d;}' file1

……但是file1file2兩者實際上都在哪裡變數抓住文件名。 (例如file2=$(mktemp)。)

所以我真正想要的是文件名的變數擴展,但命令的其餘部分沒有擴展sed,並將整個內容作為傳遞給sed命令的單一參數。

無論出於何種原因,以下方法都不起作用:

sed -i '/my regex here/{;w '"$file2"';d;}' $file1

它說“不匹配{”,我不明白為什麼。

我有什麼辦法可以做到這一點嗎?

答案1

因為您使用的是單一表達式,所以(包括)sed之後的所有內容都是w}解釋為工作文件姓名:

此參數wfile應終止編輯命令。

您可以看到,如果新增第二個命令},例如:

sed -e '/my regex here/{w '"$file2"';d;}' -e '}' $file1

那麼符合的行將會my regex here保存在名為whatever;d;}wherewhatever$file1擴充後的檔案中。
正確的語法是透過單獨的命令,或使用多個表達式:

sed -e '/my regex here/{w '"$file1" -e 'd' -e '}' $file2

或每行一個指令:

sed '/my regex here/{
w '"$file1"'
d
}
' $file2

答案2

我找到了答案堆疊溢位在“如何讓 sed 'w' 命令知道文件名在哪裡結束?”

正如 terdon 指出的那樣,問題不在於變量,但它也與大括號無關;嘗試一下sed '/^l/w testing;p',您會發現它不會拋出任何錯誤,而是將以 an 開頭的所有行寫入l名為testing;p.

問題實際上是檔案名稱後缺少換行符。

所以答案是在 sed 指令中使用內聯換行符:

sed -i '/my regex here/{;w '"$file2"'
d;}' $file1

或者,更簡潔的是,使用兩個單獨的-e參數:

sed -i -e '/my regex here/{;w '"$file2" -e 'd;}' $file1

如果您不喜歡兩個相鄰的引號(您可能很容易忽略它們),只需將 write 命令放在它自己的參數中即可:

sed -i -e '/^my regex here$/{' -e "w $file2" -e 'd;}' $file1

答案3

使用雙引號代替單引號來引用 sed 指令。並且不要忘記轉義合適的字元。

有關在 bash 中引用變數的更多信息,請參見這裡關聯

相關內容