我想在我的bash终端上执行如下命令:
sed -i '6i `sed '1!d' input.in`' out
我可以在文件的第6行插入(使用替换-i选项)sed '%1!d' input.in
命令的结果。我没有找到任何有用的东西,并尝试过`com`,$(com)和com | sed -i'6i'out,其中com
代表sed '%1!d' input.in
。我没有任何问题更改整个命令的语法,但我希望它在终端使用sed上写成一行。
感谢收听, 等待你的回答。
对于EdMorton:
Example Input:
input.in:
into a lake.
out:
Mary was runing around a pond and fell
into a lake.
Mary fell into a what?
Desired Output:
Mary was runing around a pond and fell
into a lake.
Mary fell into a what?
into a lake.
答案 0 :(得分:2)
尝试在标准输入上使用r
而不是i
。
sed '%1!d' input.in |
sed -i '6r /dev/stdin' out
如果您的平台不支持/dev/stdin
或/dev/fd/0
,请查看您的sed
是否支持-
表示标准输入...或者,在最差的情况下案件,诉诸临时档案。
正如评论者已经指出的那样,%1!d
在大多数sed
方言中似乎不是一个有效的命令,但这在这里基本上不重要。 (如果您的意思是仅打印第一行,可能您的意思是sed '1!d'
,尽管sed 'p;q'
可以更有效地执行此操作。)
答案 1 :(得分:1)
sed用于单个行上的简单替换,即全部。对于其他任何你应该使用awk。
鉴于此修改后的输入文件
$ cat input.in
a Windows folder C:\Windows\Temp
以下是您在评论中发布的sed解决方案:
$ sed '1!d' input.in > temp.of.in && sed "6i `cat temp.of.in`" out
Mary was runing around a pond and fell
into a lake.
Mary fell into a what?
a Windows folder C:WindowsTemp
这就是awk解决方案在没有临时文件的情况下更高效,更准确地执行的操作:
$ awk 'NR==1{x=$0;nextfile} FNR==6{print x} 1' input.in out
Mary was runing around a pond and fell
into a lake.
Mary fell into a what?
a Windows folder C:\Windows\Temp
注意awk解决方案保留了路径分隔符反斜杠,而sed剥离了它们。另请注意,您应该在sed命令行的末尾添加&& rm temp.of.in
来清理临时文件,并且应该使用$(..)
来执行命令,而不是过时的反引号。
awk解决方案使用GNU awk用于;nextfile
,其他awks用}NR==FNR{next
或类似替换它但是因为你使用GNU sed我假设你也有GNU awk。 / p>
请注意,如果您有兴趣使用sed并且接受它并不能完全重现输入,那么有更简单,更有效的方法来执行当前脚本所做的事情,例如:
sed "6i $(head -1 input.in)" out
甚至是你最初的想法,只是为了删除过时的反引号和1!d
的否定逻辑而重写:
sed "6i $(sed -n '1p' input.in)" out
但严重 - 只需使用awk。对于除了单独行上的简单替换之外的任何内容,它比sed更加健壮,高效,清晰,可移植,可扩展等等。
编辑要解决您的评论中的问题:
1
是惯用的,但乍一看有点棘手 - 它是一个真实条件,因此它调用打印当前输入的默认操作,相当于只写{print}
。-i
,GNU awk有-i inplace
。但要小心,因为,就像sed一样,它适用于每个输入文件,所以如果你不打印第一个文件的内容,那么当脚本完成后,第一个文件将为空。有各种各样的方法来解决这个问题,包括简单地打印文件1中的行或在BEGINFILE / ENDFILE块中打开/关闭原位编辑,请参阅https://www.gnu.org/software/gawk/manual/gawk.html#Extension-Sample-Inplace,但恕我直言awk 'script' file1 file2 > temp && mv temp file2
是最简单的最清晰,也可以移动到所有的awks / seds /无论如何。
awk '
NR==FNR { if (NR<=4) x=x $0 ORS; else nextfile }
FNR==6 { printf "%s", x }
{ print }
' input.in out
为了清楚起见,我将1
从上一个脚本更改为{ print }
。