【问题标题】:Clean output using sed使用 sed 清理输出
【发布时间】:2019-06-25 17:21:10
【问题描述】:

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

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 是一样的”

【问题讨论】:

  • 一般情况下不需要grep pattern | sed ...。您可以使用sed 进行过滤。在这种情况下:sed -n '/INFO|NOT-CLONED/s/...//p。请注意,我已将您的替换替换为 ...,因为 sed 是错误的工具。我只是指出grep | sed 是一种反模式。
  • 也可以使用cutcat clone_them.log | cut -d'|' -f3

标签: bash sed cat


【解决方案1】:

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

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

它是如何工作的:

  • -E

    使用扩展正则表达式

  • -n

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

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

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

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

变化:只返回最后一个文件夹名

要只得到last-folder-name 而没有INFO|NOT-CLONED,我们只需从输出中删除\1

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

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

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

【讨论】:

  • 谢谢,这是我一直在寻找的答案,我只是有一个疑问,如果我只需要获取没有 INFO|NOT-CLONED 的最后一个文件夹名称,我只需要删除它部分?
  • @MateoGutierrez 很高兴这对你有用。我刚刚用代码更新了答案,只得到了last-folder-name 而没有INFO|NOT-CLONED
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多