我想在 CentOS 7.2 的命令行上替换文本文件中出现的所有文本字符串。
Search-string: ).\nPORT
Replacement-string: ). \n0 closed ports\nPORT
我知道,这可以通过不同的工具来实现,例如,,,,sed
... ,但我无法找到一种简单的方法来做到这一点并能够理解命令(重要;-))。对我来说,最大的问题是换行符,没有它们,这是对.但是换行符...awk
tr
sed
任何带有解释的建议都非常受欢迎。
已编辑
输入
...
Nmap scan report for w.x.y.z (x.x.x.x)
Host is up (0.00090s latency).
PORT STATE SERVICE
21/tcp open ftp
...
Nmap scan report for w.x.y.z (x.x.x.x)
Host is up (0.00079s latency).
Not shown: 2 closed ports
PORT STATE SERVICE
22/tcp open ssh
|_banner: SSH-2.0-mpSSH_0.2.1
...
输出
...
Nmap scan report for w.x.y.z (x.x.x.x)
Host is up (0.00090s latency).
0 closed ports
PORT STATE SERVICE
21/tcp open ftp
...
Nmap scan report for w.x.y.z (x.x.x.x)
Host is up (0.00079s latency).
Not shown: 2 closed ports
PORT STATE SERVICE
22/tcp open ssh
|_banner: SSH-2.0-mpSSH_0.2.1
...
答案1
这是一种可能的方法
sed '/)\. $/ {
n
/^PORT/ i\
0 closed ports
}'
测试
$ sed '/)\. $/ {
n
/^PORT/ i\
0 closed ports
}' < input
...
Nmap scan report for w.x.y.z (x.x.x.x)
Host is up (0.00090s latency).
0 closed ports
PORT STATE SERVICE
21/tcp open ftp
...
Nmap scan report for w.x.y.z (x.x.x.x)
Host is up (0.00079s latency).
Not shown: 2 closed ports
PORT STATE SERVICE
22/tcp open ssh
|_banner: SSH-2.0-mpSSH_0.2.1
...
答案2
您可以使用N
sed 来提取模式空间中的下一行输入,然后同时处理两行。
例如,当看到 时,有条件地拉入下一行foo
,然后对两行进行替换。 (请注意,连续的行foo
会破坏这一点。)
echo -e "asf\nfoo\nbar" | sed -e '/foo/N;s/o\nb/od\nc/'
此外,GNU sed 具有-z
在 NUL 字符而不是换行符上分隔“行”的选项。这将很容易地允许您匹配跨越换行符的模式,但会导致字符串操作立即在整个输入上运行,这可能是大输入的问题。
当然应该考虑周围的结构,它可能会影响进行编辑的最佳方式。
答案3
新版本的 GNU sed 支持 -z 选项。
通常,sed 通过读取字符串直到行尾字符(换行符或回车符)来读取行。
GNU 版本的 sed 在 4.2.2 版本中添加了一个功能来使用“NULL”字符代替。如果您有使用 NULL 作为记录分隔符的文件,这会很有用。一些 GNU 实用程序可以生成使用 NULL 而不是新行的输出,例如“find . -print0”或“grep -lZ”。
当您希望 sed 在不同的行上工作时,可以使用此选项。
sed -z 's/)[.]\nPORT/). \n0 closed ports\nPORT/g' inputfile
请注意,您的示例输入后面有一个空格(0.00090s latency).