在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 ~]#