我有一个包含多行的文本文件,我想搜索包含某些文本的行并在这些行的开头添加 # 。
例如:file1 我想更改它
acnet 6801/tcp # ACNET Control System Protocol
acnet 6801/udp # ACNET Control System Protocol
dlip 7201/tcp # DLIP
dlip 7201/udp # DLIP
ssp-client 7801/tcp # Secure Server Protocol - client
ssp-client 7801/udp # Secure Server Protocol - client
我想找到位于 inputfile1 中的端口。输入文件一包含:
6801
7801
所以 file1 的最终输出将是这样的:
#acnet 6801/tcp # ACNET Control System Protocol
#acnet 6801/udp # ACNET Control System Protocol
dlip 7201/tcp # DLIP
dlip 7201/udp # DLIP
#ssp-client 7801/tcp # Secure Server Protocol - client
#ssp-client 7801/udp # Secure Server Protocol - client
我试过
cat /etc/services |grep -f ports.txt | awk '{ print"#" $g}';
但这给了我屏幕上的输出。如何在文件中更改它们?
答案1
尝试类似的方法:
awk -F"[ \t]*|/" 'NR==FNR{A[$1]; next} $2 in A { printf "#" }1' ports.txt /etc/services > newfile
如果输出正确,可以复制到/etc/services
答案2
sed '/6801\|7801/ {s/^/#/}' input
#acnet 6801/tcp # ACNET Control System Protocol
#acnet 6801/udp # ACNET Control System Protocol
dlip 7201/tcp # DLIP
dlip 7201/udp # DLIP
#ssp-client 7801/tcp # Secure Server Protocol - client
#ssp-client 7801/udp # Secure Server Protocol - client
答案3
REGEXP=$(cat ports.txt | xargs | sed -e 's/ /|/g')
sed -E -i -e "/[[:space:]]$REGEXP\// s/^/#/" inputfile1
这会根据 的内容构造一个扩展正则表达式ports.txt
,然后使用它们来选择 中 的特定地址(行)以在前面添加inputfile1
一个字符。#
正则表达式是“锚定”的,开头有一个空格,/
结尾有一个,这样您就不会匹配超出指定范围的内容 - 例如,如果没有锚点,a 25
inports.txt
不仅会匹配端口 25,还会匹配包含25
其中的某个数字,包括2501
、1025
、250
等等。
顺便说一句,如果您希望能够在 ports.txt 中添加注释,请使用以下命令:
REGEXP=$(sed -e 's/#.*//' ports.txt | xargs | sed -e 's/ /|/g')
sed -E -i -e "/[[:space:]]$REGEXP\// s/^/#/" inputfile1
上面的第一个版本将仅有的如果ports.txt
只包含端口号、空格和空行,则可以正常工作 - 任何无关的字符(尤其是在正则表达式中具有特殊含义的字符)都将导致不可预测且几乎肯定是不良结果。
第二个版本删除注释(即行上任何字符之后的所有内容,包括#
行上的任何字符),因此也允许(忽略)注释中的任何字符。
sed
如果 ports.txt 中列出的端口导致命令超出最大命令行长度,也会失败。由于该大小通常约为 128KB,因此在本例中这不太可能成为问题,但如果您将此技术用于其他任务,则值得注意。