为什么当我尝试提取部分正则表达式时 sed 失败



我在目录中有一个具有以下命名约定的文件列表:prefix_2chars_suffix
示例:currentfile_aa_belongsToprojectForDep currentfile_bb_belongsToprojectForDep等。
我想"提取前缀和后缀之间的 2 个字符。所以我想使用sed。
我尝试了以下方法:

ls currentfile_* | sed 's/currentfile_([..])_belongsToprojectForDep/1/g'

我得到:

sed:-e 表达式 #1,字符 44:未知命令:"\"

但是当我这样做时:

echo this is digit 7 in a number | sed 's/digit ([0-9])/1/'它有效,这意味着我的语法
没有错误我在这里做错了什么?

你不需要把它们放在[]之间:

ls currentfile_* | sed 's/currentfile_(..)_belongsToprojectForDep/1/g'

你也可以只使用切割:

ls currentfile_* | cut -f 2 -d _

更准确的形式也是

ls currentfile_??_belongsToprojectForDep | cut -f 2 -d _
解析

ls的输出是非常糟糕的做法。此外,sed 在您的情况下并不是真正有用(即使我在评论中读到您想学习 sed,您最好学会在特定情况下正确使用适当的工具 - 并学会解析 ls 的输出)。您可以考虑以下纯 bash 解决方案:

for i in currentfile_??_*; do
    [[ $i =~ ^[^_]+_([^_][^_])_[^_]+$ ]] && echo "${BASH_REMATCH[1]}"
done

这应该是相当强大的。如果您将其与 shopt -s nullglob 一起使用会更加强大。

  • 我们不喜欢解析 ls 的输出。我们改用 glob。在这里,glob 确保我们只循环使用由两个字符分隔的两个下划线的文件名。我们这里可能有太多的文件名,例如,像 currentfile_a__cool_file_is_very_coolcurrentfile____ilikeunderscores__ 这样的文件名会匹配。
  • 在找到的文件名中,我们将使用正则表达式进一步过滤我们想要的文件名,即那些正好有 2 个下划线的文件名(因此由两个非下划线字符分隔)。
  • ${BASH_REMATCH[1]}将扩展到第一个匹配模式(观察正则表达式中的括号)。

第一点是你的ls-pipe的对应物。最后两点是您的 sed 语句的对应点。

希望这有帮助!

最新更新