как вставить фразу после слова с помощью sed в mac

как вставить фразу после слова с помощью sed в mac

У меня есть следующий код:

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 '' ...). Смотритеэтотиэтотна stackoverflow.com.

Вторая проблема заключается в том, что 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для отключения отладочной трассировки.

Связанный контент