使用 sed 清理输出

Clean output using sed

我有一个以这种格式开头的文件

INFO|NOT-CLONED|/folder/another-folder/another-folder|last-folder-name|

我需要的是读取文件并得到这个输出:

INFO|NOT-CLONED|last-folder-name

到目前为止我有这个:

cat clone_them.log | grep 'INFO|NOT-CLONED' | sed -E 's/INFO\|NOT-CLONED\|(.*)/g'

但没有按预期工作

注意: 最后一个 "another-folder" 和“last-folder-name 是相同的

它在 awk 中更简单,因为输入文件由 | 符号正确分隔。您需要告诉 awk 输入字段由 | 分隔,输出也应分别使用 IFSOFS 保持用 | 符号分隔。

awk 'BEGIN{FS=OFS="|"}/INFO\|NOT-CLONED/{print ,,$(NF-1)}' clone_them.log
INFO|NOT-CLONED|last-folder-name

如果你想要一个 sed 解决方案:

$ sed -En 's/(INFO\|NOT-CLONED\|).*\|([^|]*)\|$//p' file
INFO|NOT-CLONED|last-folder-name

工作原理:

  • -E

    使用扩展正则表达式

  • -n

    除非我们明确告诉它,否则不要打印。

  • s/(INFO\|NOT-CLONED\|).*\|([^|]*)\|$//p

    查找包含 INFO|NOT-CLONED| 的行(将其保存在第 1 组中),然后是 .*,然后是 |,然后是任何非 | 的字符, [^|]*(保存在第 2 组),然后是行尾的 |。替换文本是第 1 组,然后是第 2 组。

    p 选项告诉 sed 在匹配成功时打印该行。由于替换仅对包含 INFO|NOT-CLONED| 的行成功,因此无需额外的 grep 过程。

变体:仅返回 last-folder-name

要只得到 last-folder-name 而没有 INFO|NOT-CLONED,我们只需要从输出中删除 </code>:</p> <pre><code>$ sed -En 's/(INFO\|NOT-CLONED\|).*\|([^|]*)\|$//p' file last-folder-name

由于我们不再需要第一个捕获组,我们可以简化并删除现在不需要的括号,以便唯一的捕获组是最后一个文件夹名称:

$ sed -En 's/INFO\|NOT-CLONED\|.*\|([^|]*)\|$//p' file
last-folder-name