提取与特定模式匹配的行 + 额外操作

Extract lines matching specific pattern + additional manipulation

给定目录列表 and/or 文件路径,我想提取包含名称与给定模式匹配的文件的目录路径,例如扩展名为 .txt 的文件。

示例输入文件:

/a/b/c/d.txt
/a/b/c/d/e.txt
f
g
h/i
/a/b/c.txt

预期输出:

/a/b/c/
/a/b/c/d/
/a/b/

如何使用 Linux 命令行工具执行此操作?我想知道以下是否是一个好的开始:

grep "\.txt" foo | <what else?>

您可以使用

awk -F/ '$NF ~ /\.txt$/{$NF="";print}' OFS=/ file

详情:

  • -F/ - 将字段分隔符设置为正斜杠
  • $NF ~ /\.txt$/ - 如果最后一个字段文本以 .txt...
  • 结尾
  • {$NF="";print} - 然后将最后一个字段文本归零并打印结果...
  • OFS=/ - 使用 / 连接字段,而不是默认的 space.

参见 online demo:

#!/bin/bash
s='/a/b/c/d.txt
/a/b/c/d/e.txt
f
g
h/i
/a/b/c.txt'
awk -F/ '$NF ~ /\.txt$/{$NF="";print}' OFS=/ <<< "$s"

输出:

/a/b/c/
/a/b/c/d/
/a/b/

这个sed有效吗?

sed 's#\(.*/\).*##;/^[a-z]/d' input_file

输出

$ sed 's#\(.*/\).*##;/^[a-z]/d'
/a/b/c/
/a/b/c/d/
/a/b/

(假设想要的输出在第2行和第3行尾部有/,否则与第1行输出不一致...)

看看这个:

sed -En '/\.txt$/s!(.*/).*!!p' foo

哪里

  • -E就是用()代替\(\)进行分组
  • -n 告诉 Sed 在默认情况下不打印模式 space
  • /\.txt$/ 只匹配那些以 .txt
  • 结尾的行
  • s 运行 我们匹配的那些行的替换 /\.txt$/
  • 使用
  • ! 而不是 / 作为分隔符,因为这样我们就不必转义 /
  • (.*/).* 匹配整行,但只捕获并包括最后一个 /
  • </code> 用我们捕获的部分替换该行</li> <li><code>p 标志告诉 Sed 打印行