如何在跳过一些文件和目录的同时移动文件

How to move files en-masse while skipping a few files and directories

我正在尝试编写一个 shell 脚本来移动所有文件,但以 .sh.py 结尾的文件除外。我也不想移动目录。

这是我目前得到的:

cd FILES/user/folder
shopt -s extglob
mv !(*.sh|*.py) MoveFolder/ 2>/dev/null 
shopt -u extglob

这将移动所有文件,但包含 .sh.py 的文件除外,但所有目录也会移动到 MoveFolder

我想我可以重命名这些文件夹,但其他脚本已经为它们的工作分配了这些文件夹,所以重命名可能会给我带来更多麻烦。我也可以添加文件夹名称,但每当其他人创建文件夹时,我都必须将其名称添加到脚本中,否则它也会被移动。

如何改进此脚本以跳过所有文件夹?

您必须检查每个元素以查看它是否是一个目录,以及它的扩展名:

for f in FILES/user/folder/*
do
   extension="${f##*.}"
   if [ ! -d "$f" ] && [[ ! "$extension" =~ ^(sh|py)$ ]]; then
       mv "$f" MoveFolder
   fi
done

否则,您也可以使用 find -type f 并使用 maxdepth 和正则表达式做一些事情。

文件名的正则表达式基于 Check if a string matches a regex in Bash script, extension extracted through the solution to Extract filename and extension in Bash.

为此使用 find

find -maxdepth 1 \! -type d \! -name "*.py" \! -name "*.sh" -exec mv -t MoveFolder {} +

它的作用:

  • find: 找东西...
  • -maxdepth 1: 当前目录中...
  • \! -type d: 那不是目录...
  • \! -name "*.py: 并且其名称不以 .py...
  • 结尾
  • \! -name "*.sh: 并且其名称不以 .sh...
  • 结尾
  • -exec mv -t MoveFolder {} +: 并将它们移动到目录 MoveFolder

-exec 标志是特殊的:与之前作为条件的标志相反,这个标志是一个动作。对于每个匹配项,结束以下命令的 + 指示 find 在命令末尾,在标记为 {} 的位置聚合文件名。找到所有文件后,find 执行生成的命令(即 mv -t MoveFolder file1 file2 ... fileN)。