我试图q
在 sed 中使用命令(模仿head -n
并仅获取前几行),然后s/
仅在这些行上替换模式。
如果我省略第一个表达式,则替换将完全按照我想要的方式进行,但是当我尝试仅在第一行应用替换时,只会发生第一个替换。我使用 sed 而不是 head 因为我想-i
稍后使用该命令。
sed -e '2q' -e 's/\([0-9]\{4\}[[:space:]]\)\{3\}/XXXX XXXX XXXX /g' file
答案1
表达式的顺序很重要。这是一个例子:
cat file
a
a
a
a
< file sed '2q; s/a/b/g'
b
a
< file sed 's/a/b/g; 2q'
b
b
所以你必须戒掉后你已经替换了第二行。目前,您在应用替换表达式之前退出。或者如果您更喜欢-e
语法:
< file sed -e 's/a/b/g' -e '2q'
稍微不同的情况:
如果您只想对前两行应用替换,但打印整个文件,可能-i
一起使用就地执行此操作,您可以这样做:
< file sed '1,2 s/a/b/g' file
b
b
a
a
我们匹配一个行范围,1,2
并且仅对于该范围,我们执行以下表达式。如果我们有许多表达式要在这个范围内运行,我们将它们包含在 内{}
,如下所示:
< file sed '1,2{s/a/b/g; s/c/d/g;}' file
答案2
不要为了-i
.而牺牲你的软件。做head -n file > tmp && mv tmp file
并不是什么大事,这就是 sed 内部正在做的事情。另外,就像 GNU sed 一样-i
,GNU awk-i inplace
也通常会让您编写一个更清晰、更容易增强的脚本,而不是尝试使用s/old/new/
sed 进行简单的操作。
目前尚不清楚您是否要修改所有行并仅打印前 2 行,还是打印所有行但仅修改前 2 行或其他内容,因此这里有几种可能性:
- 仅打印前 2 个输入行并修改它们:
awk '{gsub(/\([0-9]{4}[[:space:]]\){3}/,"XXXX XXXX XXXX "); print} NR==2{exit}' file
- 打印所有输入行,但仅修改其中的前两行:
awk 'NR<=2{gsub(/\([0-9]{4}[[:space:]]\){3}/,"XXXX XXXX XXXX ") {print}' file
使用 GNU awk 进行“就地”编辑,就像使用 GNU 一样sed -i
:
awk -i inplace '...' file