使用sed或awk在特定行号处插入一行
我有一个脚本文件,我需要用另一个脚本修改它,以便在第8行插入文本 要插入的字符串:使用sed或awk在特定行号处插入一行,sed,awk,Sed,Awk,我有一个脚本文件,我需要用另一个脚本修改它,以便在第8行插入文本 要插入的字符串:Project\u Name=sowstest,插入名为start的文件中 我试图使用awk和sed,但我的命令变得混乱 sed -i '8i8 This is Line 8' FILE 在第8行插入 8 This is Line 8 归档 -i直接对文件进行修改,不输出到标准输出,正如glenn jackman在评论中提到的那样 awk答案 awk -v n=8 -v s="Project_Name=sows
Project\u Name=sowstest
,插入名为start
的文件中
我试图使用awk和sed,但我的命令变得混乱
sed -i '8i8 This is Line 8' FILE
在第8行插入
8 This is Line 8
归档
-i
直接对文件进行修改,不输出到标准输出,正如glenn jackman在评论中提到的那样 awk答案
awk -v n=8 -v s="Project_Name=sowstest" 'NR == n {print s} {print}' file > file.new
ed
答案
ed file << END
8i
Project_Name=sowstest
.
w
q
END
ed file对于那些使用非GNU的SunOS的用户,以下代码将有所帮助:
sed '1i\^J
line to add' test.dat > tmp.dat
- ^J与^V+^J一起插入
- 在“1i”之后添加换行符
- \必须是行的最后一个字符
- 命令的第二部分必须在第二行中
POSIXsed
(例如OSX的sed
,下面的sed
)要求i
后跟反斜杠和换行符。此外,至少OS 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
要替换行,可以使用带有数字地址的c
(更改)或s
(替换)命令:
$ 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
传递的变量中的反斜杠,但不解释使用环境传递的变量中的反斜杠:
$ seq 3|awk -v v='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定义的。Perl解决方案:
又快又脏:
perl-lpe'如果$==8'文件
-l
剥离新行并将其添加回,从而消除了对“\n”的需要
-p
在输入文件上循环,打印每一行
-e
以单引号执行代码
$。
是行号
等效于@glenn的awk解决方案,使用命名参数:
perl-slpe'print$s if$。==$n'--n=8-s=“Project\u Name=sowstest”文件
-s
启用基本参数解析器
--
防止标准perl参数解析器解析-n和-s
位置命令参数:
perl-lpe'BEGIN{$n=shift;$s=shift};如果$=,则打印$s$n'8“项目名称=sowstest”文件
环境变量:
ENV
是包含所有环境变量的哈希
Getopt将参数解析为哈希%o:
perl-MGetopt::Std-lpe'BEGIN{getopt(“ns”,\%o)};如果$==打印$o{s}$o{n}'-n8-s“Project_Name=sowstest”文件
Getopt::长的和更长的选项名称
perl-MGetopt::Long-lpe'BEGIN{GetOptions(\%o,“line=i”,“string=s”);如果$.==打印$o{string}$o{line}'--第8行--字符串“Project_Name=sowstest”文件
Getopt是推荐的标准库解决方案。
对于一行perl脚本来说,这可能有点过头了,但是可以做到OSX/macOS/FreeBSDsed
-i
标志在macOSsed
上的工作方式与GNUsed
上的工作方式不同
以下是在macOS/OS X上使用它的方法:
sed -i '' '8i\
8 This is Line 8' FILE
有关更多信息,请参见。sed-e'8iProject\u Name=sowstest'-i使用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 ~]#
[root@node23 ~]# sed -e '5ixxx (inserted) "line" xxx' -i a_file
[root@node23 ~]# cat -n a_file
1 Line #1
2 Line #2
3 xxx inserted line xxx
4 Line #3
5 xxx (inserted) "line" xxx
6 Line #4
7 Line #5
8 Line #6
9 Line #7
10 Line #8
11 Line #9
12 Line #10
[root@node23 ~]#
[root@node23~]#for((i=1;i)是一个文件
[root@node23~]#cat a#U文件
第1行
第2行
第3行
第4行
第5行
第6行
第7行
第8行
第9行
第10行
[root@node23~]#sed-e'3ixxx插入行xxx'-i a#u文件
[root@node23~]#cat-一个a#u文件
1行#1$
2行#2$
3 xxx插入行xxx$
4行#3$
5行#4$
6行#5$
7行#6$
8行#7$
9行#8$
10行#9$
11行#10$
[root@node23 ~]#
[root@node23~]#sed-e'5ixxx(插入)“行”xxx'-i a_文件
[root@node23~]#cat-n a_文件
1行#1
2行#2
3 xxx插入行xxx
4行#3
5 xxx(插入)“行”xxx
6行#4
7行#5
8行#6
9行#7
10行#8
11行#9
12行#10
[root@node23 ~]#
sed-i'-e$'4 a\\n''Project\u Name=sowstest'启动
- 这条线在macOS中运行良好
是的,-i开关特定于GNU-sed。否。-我的意思是“就地修改指定的文件”插入与追加是通过“8isomething”与“8asomething”实现的,独立于-i-switch.mac用户:使用自制,brew安装gnu sed
,然后与gsed
一起使用,这非常有用!我是否可以在行的开头插入空格?我注意到sed没有注意初始空格ace…@elju:是的,用反斜杠遮住它:sed'8i\8这是第8行”文件
@glenn jackman我需要输入#定义服务器@”http://10.35.42.54/ms0.8"
到某一行。我怎么能做到这一点呢?我想内文只需要用backslashes@waLLe,从它开始,它很好地描述了awk是如何工作的配对,第二个没有条件,这意味着对每条记录都执行操作。读完后,如果还有问题,请告诉我。@glennjackman就快到了。。只是没有得到这个:file>file.new“file”表示awk正在处理的文件的名称。
是shell符号,因此awk的输出存储在名为“file.new”的文件中.Chris,感谢你花时间解释了这一切,并把它布置得如此漂亮,但哇,这就是我不喜欢perl的原因。插入后第3行的尾随$
来自哪里?它来自-A
标志到cat
:)如果要插入的字符串包含引号、括号等,该怎么办?请参阅上面的文本更新。这意味着您必须根据需要转义这些字符。是否可以使用变量而不是字符串文本内联来执行此操作?@AndyRay使用double
[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 ~]#
[root@node23 ~]# sed -e '5ixxx (inserted) "line" xxx' -i a_file
[root@node23 ~]# cat -n a_file
1 Line #1
2 Line #2
3 xxx inserted line xxx
4 Line #3
5 xxx (inserted) "line" xxx
6 Line #4
7 Line #5
8 Line #6
9 Line #7
10 Line #8
11 Line #9
12 Line #10
[root@node23 ~]#