使用 sed 从文件中提取一行的一部分

Mer*_*cer 25 sed

我想从文件中读取一行的一部分。例如:

POP3_SERVER_NAME = 本地主机

我只想返回localhost,使用 sed。

这段文字在第三行。我这样做是为了提取行:

sed -n '3p' installation.sh
Run Code Online (Sandbox Code Playgroud)

如何只提取localhost部分?

Mik*_*ll' 32

awk 在这里可能是一个更好的工具。

$ cat test.dat
LINE 1
LINE 2
POP3_SERVER_NAME = localhost
Run Code Online (Sandbox Code Playgroud)

搜索包含“POP3_SERVER_NAME”的行;打印最后一个字段。这不依赖于 POP3_SERVER_NAME 总是在第 3 行,这可能是一件好事。

$ awk '/POP3_SERVER_NAME/{print $NF}' test.dat
localhost
Run Code Online (Sandbox Code Playgroud)

根据您的应用程序,您可能需要使正则表达式更加严格。例如,您可能只想匹配以 POP3_SERVER_NAME开头的那一行。

$ awk '/^POP3_SERVER_NAME/{print $NF}' test.dat
localhost
Run Code Online (Sandbox Code Playgroud)

使用 sed 不太直观。(谢谢,我知道这很讽刺。)在任何地方解决包含 POP3_SERVER_NAME 的行。将行首到“=”后面的可选空格的所有文本替换为空字符串。然后打印。

sed -n -e '/POP3_SERVER_NAME/ s/.*\= *//p' test.dat
Run Code Online (Sandbox Code Playgroud)

  • @Marcel,您可以使用 `-F` 将 `awk` 使用的分隔符从空格更改为其他内容。例如:在您提到的情况下,`-F "="` 将使用 `=` 作为分隔符。 (4认同)
  • `awk` 命令很好 - 但前提是你在 `=` 周围有空格。它不适用于`POP3_SERVER_NAME=localhost`。 (3认同)

Gil*_*il' 9

p删除行中不需要的部分的替换替换命令。

sed -n '3 s/^[^=]*= *//p' installation.sh
Run Code Online (Sandbox Code Playgroud)

您可能希望按关键字而不是按位置匹配行。

sed -n 's/^ *POP3_SERVER_NAME *= *//p' installation.sh
Run Code Online (Sandbox Code Playgroud)


小智 7

看起来你有一个配置文件。你可以做的类似于 Adam Siemeon/slm 的建议:

sed -nr 's/[^=]+=\s*(.+)$/\1/p' filename
Run Code Online (Sandbox Code Playgroud)

其中[^=]不包括所有“=”字符,+表示一个或多个相同类型的字符,这后跟一个实际=\s任何空白(包括突出部\t和新的线\n\r\n和纯的空间“”,而*装置零个或多个相同类型的, 括号捕获里面的内容以将匹配的字符序列放入 \1, \2, ..., \n 替换占位符中,$表示行的结尾。这遵循以下典型的替换模式:s/.../.../modifiers。命令行选项-r代表扩展正则表达式语法(为了方便起见),-n意味着在明确请求之前或除非明确请求,否则不输出任何内容。p修饰符打印出结果。

您可以使用g修饰符进行全局搜索,例如:

sed -nr 's/[^=]+=\s*(.+)$/\1 /pg' filename  # note the space after \1
Run Code Online (Sandbox Code Playgroud)

使您获得通过分隔字符串' '(可能是\n\t或你有什么),你可以轻松地处理。

如果您的值前面是等式字符,直到行尾,并且后面没有注释或其他语义偏离简单“值”的字符,则两者都是有效的。


编辑:

我还不能在这里评论其他人的帖子。要指示该行,只需传递行号,在您的情况下为 3,在s起始引号字符之前或之前(就像在 vim 中一样)。

sed -nr '3s/[^=]+=\s*(.+)$/\1/p' filename
Run Code Online (Sandbox Code Playgroud)

请看一看info sed。例如,您对 3.2 和 4.7 尤其感兴趣。


小智 6

您可以使用 cut 命令,将分隔符设置为“=”,然后像这样打印第二个字段:

cut -d'=' -f2
Run Code Online (Sandbox Code Playgroud)


Ada*_*ion 5

echo "POP3_SERVER_NAME = localhost" | sed 's/.*= //'
localhost
Run Code Online (Sandbox Code Playgroud)

或者,如果您在文件中有内容:

sed 's/.*= //' somefile.txt
localhost
Run Code Online (Sandbox Code Playgroud)

  • @Mercer - 查看我添加到答案中的更新。 (2认同)