我有以下代码:
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 上。
第二个问题是该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
关闭调试跟踪。