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

ここで問題が 2 つあります。1 つ目は、macOS バージョンの では、バックアップ ファイルに使用する拡張子を指定するためsedの明示的な引数を-iオプションに指定する必要があることです。バックアップが必要ない場合は、その後に空の引数を渡す必要があります ( sed -i '' ...)。これそしてこれstackoverflowで。

2 番目の問題は、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 の更新に関する無関係な内容も多数含まれます。) これによってすべてが 1 行に収まる唯一の理由は、コマンドの末尾の改行がsed欠落している場合であると考えられます。

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

ちなみに、set +xデバッグ トレースをオフにするには を使用します。

関連情報