在sed或awk的特定行号处插入一行

我有一个脚本文件,我需要修改与另一个脚本插入文本在第8行。

要插入的string: Project_Name=sowstest ,放入名为start的文件中。

我试图使用awk和sed,但我的命令变得乱码。

 sed -i '8i8 This is Line 8' FILE 

插入第8行

 8 This is Line 8 

到文件FILE中

-i直接修改文件的文件,没有输出到标准输出,正如glenn jackman的评论所述。

答案

 ed file << END 8i Project_Name=sowstest . w q END 

. 在它自己的行结束input模式; w写道; q退出。 GNU ed有一个wq命令来保存和退出,但是老版本没有。

进一步阅读: https : //gnu.org/software/ed/manual/ed_manual.html –

awk的答案

 awk -vn=8 -vs="Project_Name=sowstest" 'NR == n {print s} {print}' file > file.new 

POSIX sed (例如OS X的sed ,下面的sed )要求i后面跟着一个反斜杠和一个换行符。 另外至lessOS X的sed在插入的文本之后不包括换行符:

 $ seq 3|gsed '2i1.5' 1 1.5 2 3 $ seq 3|sed '2i1.5' sed: 1: "2i1.5": command i expects \ followed by text $ seq 3|sed $'2i\\\n1.5' 1 1.52 3 $ seq 3|sed $'2i\\\n1.5\n' 1 1.5 2 3 

要replace一行,可以使用带有数字地址的c (change)或s (substitute)命令:

 $ seq 3|sed $'2c\\\n1.5\n' 1 1.5 3 $ seq 3|gsed '2c1.5' 1 1.5 3 $ seq 3|sed '2s/.*/1.5/' 1 1.5 3 

使用awk替代方法:

 $ seq 3|awk 'NR==2{print 1.5}1' 1 1.5 2 3 $ seq 3|awk '{print NR==2?1.5:$0}' 1 1.5 3 

awk在用-v传递的variables中解释反斜杠,但不在通过ENVIRON传递的variables中解释反斜杠:

 $ seq 3|awk -vv='a\ba' '{print NR==2?v:$0}' 1 a 3 $ seq 3|v='a\ba' awk '{print NR==2?ENVIRON["v"]:$0}' 1 a\ba 3 

ENVIRON-v都由POSIX定义。

对于非GNU的SunOS用户,以下代码将有所帮助:

 sed '1i\^J line to add' test.dat > tmp.dat 
  • ^ J用^ V + ^ J插入
  • 在'1i之后添加换行符。
  • 必须是该行的最后一个字符。
  • 命令的第二部分必须在第二行。

Perl解决scheme:

快速和肮脏:

perl -lpe 'print "Project_Name=sowstest" if $. == 8' file

  • -l去掉换行符并将其添加回去,从而不需要“\ n”
  • -p循环input文件,打印每一行
  • -e用单引号执行代码

$. 是行号

相当于@ glenn的awk解决scheme,使用命名参数:

perl -slpe 'print $s if $. == $n' -- -n=8 -s="Project_Name=sowstest" file

  • -s启用了一个基本的参数parsing器
  • --防止-n和-s被标准的perl参数parsing器parsing

位置命令参数:

perl -lpe 'BEGIN{$n=shift; $s=shift}; print $s if $. == $n' 8 "Project_Name=sowstest" file

环境variables:

 setenv n 8 ; setenv s "Project_Name=sowstest" echo $n ; echo $s perl -slpe 'print $ENV{s} if $. == $ENV{n}' file 

ENV是包含所有环境variables的散列

Getopt将参数parsing为哈希%o:

perl -MGetopt::Std -lpe 'BEGIN{getopt("ns",\%o)}; print $o{s} if $. == $o{n}' -- -n 8 -s "Project_Name=sowstest" file

Getopt ::长和更长的选项名称

perl -MGetopt::Long -lpe 'BEGIN{GetOptions(\%o,"line=i","string=s")}; print $o{string} if $. == $o{line}' -- --line 8 --string "Project_Name=sowstest" file

Getopt是推荐的标准库解决scheme。
这可能是perl脚本perl脚本的矫枉过正,但是可以做到

OS X / macOS sed

-i标志在macOS sed上的工作方式与GNU sed

以下是在macOS / OS X上使用它的方法:

 sed -i '' '8i\ 8 This is Line 8' FILE 

请参阅man 1 sed了解更多信息。

sed -e '8iProject_Name=sowstest' -i start使用GNU sed

样品运行:

 [root@node23 ~]# for ((i=1; i<=10; i++)); do echo "Line #$i"; done > a_file [root@node23 ~]# cat a_file Line #1 Line #2 Line #3 Line #4 Line #5 Line #6 Line #7 Line #8 Line #9 Line #10 [root@node23 ~]# sed -e '3ixxx inserted line xxx' -i a_file [root@node23 ~]# cat -An a_file 1 Line #1$ 2 Line #2$ 3 xxx inserted line xxx$ 4 Line #3$ 5 Line #4$ 6 Line #5$ 7 Line #6$ 8 Line #7$ 9 Line #8$ 10 Line #9$ 11 Line #10$ [root@node23 ~]#