如何在 mac 中使用 sed 在單字後插入片語

如何在 mac 中使用 sed 在單字後插入片語

我有以下程式碼:

sed  -i  "/#alias/a alias ll='ls -laGh'" /etc/zshrc
sed  -i  "/#alias/a alias l='ls -l'" /etc/zshrc

在檔案 /etc/zshrc 中我有:

#alias

但是當執行程式碼時它會拋出以下錯誤:

sed: 1: "/etc/zshrc": invalid command code z

我不明白發生了什麼

應該:

#alias
alias ll='ls -laGh'
alias l='ls -l'

它不為我服務:

#alias
alias ll='ls -laGh' alias l='ls -l'

答案1

這裡有兩個問題。第一個是 macOS 版本sed需要一個明確的參數來-i告訴它備份檔案使用什麼副檔名;如果您不想備份,則需要在其後傳遞一個空參數 ( sed -i '' ...)。看在堆疊溢位上。

第二個問題是該a指令需要在要新增的字串之前有一個轉義換行符,並在其後面有一個換行符。來自[man頁]:

 [1addr]a\
 text    Write text to standard output immediately before each attempt to
         read a line of input, whether by executing the ``N'' function or
         by beginning a new cycle.

考慮到這兩點,這應該可以滿足您的要求:

sed -i '' "/#alias/a\\
alias ll='ls -laGh'
" /etc/zshrc

如果您想避免在命令字串中出現明確換行符,可以定義nl=$'\n', 然後使用 來${nl}代替顯式換行符。如果您想一次添加多行,我傾向於使用循環來建構一個sed命令,一次添加所有行:

nl=$'\n'
sedcmd=""
for aliascmd in "alias ll='ls -laGh'" "alias l='ls -l'"; do
    sedcmd+="a\\${nl}${aliascmd}${nl};"
done
sed -i '' "/#alias/ { ${sedcmd} }" /etc/zshrc

或者,如果您喜歡執行多個命令:

nl=$'\n'
sed -i '' "/#alias/a\\${nl}alias ll='ls -laGh'${nl}" /etc/zshrc
sed -i '' "/#alias/a\\${nl}alias l='ls -l'${nl}" /etc/zshrc

如果最後一個選項仍然不起作用,請運行set -x然後重試。假設您正在使用 zsh,您應該會看到類似這樣的內容:

+zsh:10> sed -i '' $'/#alias/a\\nalias ll=\'ls -laGh\'\n' /etc/zshrc
+zsh:11> sed -i '' $'/#alias/a\\nalias l=\'ls -l\'\n' /etc/zshrc

(只有 中的數字+zsh:something會有所不同,而且還會有很多與更新終端 cwd 無關的內容。)我能想到的將所有內容放在一行的唯一原因是,如果換行符末尾該sed命令丟失:

+zsh:11> sed -i '' $'/#alias/a\\nalias l=\'ls -l\'\n' /etc/zshrc
                                                  ^^
                                          this bit here

順便說一句,用於set +x關閉調試追蹤。

相關內容