当我试图提取部分正则表达式时,为什么sed会失败?

时间:2013-09-14 10:53:23

标签: regex linux bash sed cygwin

我有一个目录中具有以下命名约定的文件列表: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/'
它有效,这意味着我没有得到关于我的语法的错误 我在这里做错了什么?

2 个答案:

答案 0 :(得分:2)

您无需将它们放在[]

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

你也可以使用cut:

ls currentfile_* | cut -f 2 -d _

更准确的形式是

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

答案 1 :(得分:0)

解析 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 语句的对应部分。

希望这有帮助!