繁体   English   中英

如何在sed中将命令的结果作为字符串参数输入

[英]How to input a command's result as a string argument in sed

我想在我的bash终端上执行以下命令:

sed -i '6i `sed '1!d' input.in`' out

通过它我可以在sed '%1!d' input.in命令的结果的文件输出的第6行插入(替换-i选项)。 我没有发现任何有用的东西,并且尝试了`com`,$(com)和com | sed sed '%1!d' input.in ,其中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.

尝试在标准输入而不是i上使用r

sed '%1!d' input.in |
sed -i '6r /dev/stdin' out

如果您的平台不支持/dev/stdin/dev/fd/0 ,请查看您的sed支持-表示标准输入...,或者在最坏的情况下,使用临时文件。

正如评论者已经指出的那样,在大多数sed方言中, %1!d似乎不是有效的命令,但是在此基本上不重要。 (如果只打印第一行,则可能是sed '1!d' ,尽管sed 'p;q'更有效。)

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

请注意,awd解决方案保留了路径分隔符反斜杠,而sed则将其删除。 还要注意,您确实应该在sed命令行的末尾添加&& rm temp.of.in以清理临时文件,并且应该使用$(..)执行命令,而不要使用过时的反引号。

awk解决方案对;nextfile使用GNU awk,对于其他awks,您可以将其替换为}NR==FNR{next或类似名称,但由于您使用的是GNU sed,所以我也假设您也有GNU awk。

请注意,如果您对DID渴望使用sed并接受它并不能完全重现输入,那么可以使用更简单,更有效的方法来执行当前脚本的操作,例如:

sed "6i $(head -1 input.in)" out

甚至是您最初的想法,只需重写一下即可消除过时的反引号和1!d否定逻辑:

sed "6i $(sed -n '1p' input.in)" out

但是请认真使用-只需使用awk。 除了在单个行上进行简单替换以外,其他任何事情都比sed健壮,高效,清晰,可移植,可扩展等。

编辑以解决您的评论中的问题:

  1. 您能解释一下awk上的参数吗? 没有参数,只有一个脚本说:如果这是从第一个文件读取的第一行,请将其保存在变量x中,然后移至下一个文件。 如果这是第二个文件的第6行,则打印变量x的内容。 对于第二个文件的每一行,打印它( 1是惯用但乍一看有点棘手-这是一个真正的条件,因此调用打印当前输入的默认操作,相当于只是写{print}
  2. 我如何将输出文件替换为out文件(不使用'>'),如选项-i在sed上所做的,并避免将其打印到stdout? 就像GNU sed has -i ,GNU awk has -i inplace 但是要小心,因为与sed一样,它适用于每个输入文件,因此,如果您不打印第一个文件的内容,那么当脚本完成后,第一个文件将为空。 有多种处理方法,包括简单地打印文件1中的行或在BEGINFILE / ENDFILE块中打开/关闭就地编辑,请参阅https://www.gnu.org/software/gawk/manual/gawk.html# Extension-Sample-Inplace ,但是恕我直言, awk'script'file1 awk 'script' file1 file2 > temp && mv temp file2是最简单和最清晰的,并且可移植到所有awk / seds /任何地方。
  3. 另外,是否有一个多行解决方案,例如从“ input.in”中取出“第1至4行”,并将其放在“ out”的第6行中? 没问题:

awk '
    NR==FNR { if (NR<=4) x=x $0 ORS; else nextfile }
    FNR==6 { printf "%s", x }
    { print }
' input.in out

为了清楚起见,我将前一个脚本的1更改为{ print }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM