Bash - 重命名包含给定正则表达式模式的所有文件

Bash - 重命名包含给定正则表达式模式的所有文件

我目录中有一些文件,它们全都包含字符串“HG-U133A”或“HG-U133B”。我想编写一个脚本,可以遍历目录中的所有文件,并将所有“HG-U133A”文件重命名为“A_”前缀,将所有“HG-U133B”文件重命名为“B_”前缀。

所以如果这些是我的目录中的文件

> grep "HG-U133[AB]" *
fileA.txt: HG-U133A
fileB.txt: HG-U133A
fileC.txt: HG-U133B
fileD.txt: HG-U133A
fileE.txt: HG-U133B

我想编写一个脚本,可以将这些文件重命名为

> ls
A_fileA.txt
A_fileB.txt
B_fileC.txt
A_fileD.txt
B_fileE.txt

我真的希望得到帮助。谢谢

答案1

这是一个便携式的解决方案,不属于Bash 陷阱 1

for file in *; do
  [ -f "$file" ] || continue
  grep -q -- HG-U133A "$file" && { mv -- "$file" "A_$file"; continue; }
  grep -q -- HG-U133B "$file" && mv -- "$file" "B_$file"
done

笔记:

  • *与点文件不匹配,但您在grep调用中使用了它,所以我认为该行为适合您或您知道如何更改它。
  • *确实匹配目录。您的grep调用没有选项,因此可能使其处理目录。该脚本会跳过任何非常规文件,其主要目的是跳过目录,而不必费心grep为它们运行(这无论如何都会失败)。
  • 双破折号(--)的解释如下:(双破折号)是什么--意思?(也称为“裸双破折号”)?这是为了防止任何文件名以破折号开头。如果我们使用./*而不是 ,*我们就不需要它了。
  • 您说的是“要么……要么……”,我将其解释为“对于给定文件,最多只有一个字符串会匹配”。因此,continue在第一个之后。它的存在是为了避免白白grep调用第二个。grep
  • 如果您预计有许多文件带有HG-U133B并且只有少数带有,HG-U133A那么请考虑HG-U133B先进行测试。

优点:

  • 可移植性,
  • 稳健性(无论文件名如何,代码都应该运行良好)。

坏处:

  • 每个常规文件至少产生一个grep进程远非最佳;如果要检查的文件数较多,这可能会减慢速度。

答案2

以下命令bash可以完成此操作:

for file in `grep -l HG-U133A *` ; do mv "$file" "A_$file" ; done
for file in `grep -l HG-U133B *` ; do mv "$file" "B_$file" ; done

相关内容