如何在 sed 行删除中使用变量

如何在 sed 行删除中使用变量

我有一个值为 6 的变量

$ echo $line_number
6

当我使用 sed 删除除 0 - 6 之外的所有行时,它按预期工作

$ sed "0,6!d" ~/myfile

当我尝试用变量替换数字 6 时,出现错误

$ sed "0,$line_number!d" ~/myfile
bash: !d": event not found

答案1

这里的问题是!in 中的字符bash,当交互时,即使在双引号内也会触发历史扩展

该功能来自 csh(实际上更糟糕),并且在 bash 和 zsh 中也可以找到,但在其他方面不是标准sh功能。

bashand中zsh,与 相反csh,历史扩展不会发生在单引号内,因此sed '0,6!d'没问题。但sed "0,6!d"还不行。在交互式bashshell 中,!d展开到包含d.

您可以!通过以下方式删除 的特殊含义:

sed "0,$line_number"'!d'

我个人禁用历史扩展功能,因为现代 shell 具有更好的交互式等效功能。我在zshwith中禁用了它,您也可以在withset +o banghist中禁用它(实际上,为了与 1997 年的 3.1.2 兼容而将其添加为别名,因此也可以在 with 中使用)。在 中,您可以使用 禁用历史记录扩展。实际上,等效的方法也适用于和。bashset +o histexpandzshhistexpandbanghistbashset +o histexpandzsh(t)cshset histcharshistchars=bashzsh

请注意,该0地址是 GNUsed扩展。可移植的是,您可以使用head它(这也会更有效):

head -n "$line_number"

对于sed可移植的,您可以使用:

sed "${line_number}q"

这也更有效,因为在sed行之后停止读取而不是继续读取但丢弃所有其他行。$line_number

相关内容