2

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

4

2 回答 2

2

您不需要将它们放在[]

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

你也可以只使用cut:

ls currentfile_* | cut -f 2 -d _

更准确的形式是

ls currentfile_??_belongsToprojectForDep | cut -f 2 -d _
于 2013-09-14T10:58:36.647 回答
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语句相对应。

希望这可以帮助!

于 2013-09-14T11:59:46.770 回答