У меня есть следующий код:
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
для отключения отладочной трассировки.