如何在Bash中使用正则表达式捕获文件名的开头?

时间:2018-03-13 23:57:02

标签: regex bash

我在名为edit_file_names.sh的目录中有许多文件,每个文件名都包含?。我想使用Bash脚本缩短?之前的文件名。例如,这些将是我当前的文件名:

test.file.1?twagdsfdsfdg
test.file.2?
test.file.3?.?

运行脚本后,这些将是我想要的文件名:

test.file.1
test.file.2
test.file.3

但是,我似乎无法捕获正则表达式中文件名的开头,以用于重命名文件。这是我目前的剧本:

#!/bin/bash
cd test_file_name_edit/

regex="(^[^\?]*)"

for filename in *; do
  $filename =~ $regex
  echo ${BASH_REMATCH[1]}
done

此时我只是试图打印每个文件名的开头,以便我知道我正在捕获正确的字符串,但是,我收到以下错误:

./edit_file_names.sh: line 7: test.file.1?twagdsfdsfdg: command not found

./edit_file_names.sh: line 7: test.file.2?: command not found

./edit_file_names.sh: line 7: test.file.3?.?: command not found

如何修复代码以成功捕获这些文件名的开头?

2 个答案:

答案 0 :(得分:1)

您错过了测试命令[[ ]]

for filename in *; do
  [[ $filename =~ $regex ]] && echo ${BASH_REMATCH[1]}
done

答案 1 :(得分:1)

正则表达式可能不是这项工作的最佳工具。相反,我建议使用bash parameter expansion。例如:

#!/bin/bash

files=(test.file.1?twagdsfdsfdg test.file.2? test.file.3?.?)

for f in "${files[@]}"; do
  echo "${f} shortens to ${f%%\?*}"
done

打印

test.file.1?twagdsfdsfdg shortens to test.file.1
test.file.2? shortens to test.file.2
test.file.3?.? shortens to test.file.3

此处,${f%%\?*}展开f并修剪与?匹配的最长后缀,后跟任意字符(?必须转义,因为它是通配符字符)。