用于将文件夹名称复制并添加到多个子目录中的文件的Shell脚本

时间:2015-04-28 13:24:02

标签: linux shell unix rename batch-rename

我有几个文件夹,其中不同的图像共享文件名,文件夹结构如下:

/parent/folder001/img001.jpg
/parent/folder001/img002.jpg
/parent/folder002/img001.jpg
/parent/folder002/img002.jpg
/parent/folder003/img001.jpg
/parent/folder003/img002.jpg
...

并希望将这些文件复制/重命名为新文件夹,如下所示:

/newfolder/folder001_img001.jpg
/newfolder/folder001_img002.jpg
/newfolder/folder002_img001.jpg
/newfolder/folder002_img002.jpg
/newfolder/folder003_img001.jpg
/newfolder/folder003_img002.jpg
...

(如果newfolder不是父文件的子文件夹,那可能会更好,因为这可能最终导致非常奇怪的递归。)

包含图片的文件夹都没有任何子文件夹。

理想情况下,我希望能够重复使用脚本来更新" newfolder,因为我可能需要在以后添加更多包含文件夹的图像。

如何使用shell脚本完成此操作?

2 个答案:

答案 0 :(得分:3)

我会用这样的东西:

find -type f -exec sh -c 'f={}; fnew=$(rev <<< "$f" | sed 's~/~_~' | rev); echo "mv $f $fnew"' \;

这将在当前目录结构中查找文件并执行以下操作:

  • 获取文件名
  • 将最后/替换为_
  • echo "cp $old_file $new_file"

运行此操作并看到它打印出正确的命令后,删除echo以便它有效地执行mv命令。

我知道fnew=$(rev <<< "$f" | sed 's~/~_~' | rev)是一个有点难看的技巧,但我找不到用/替换上一个_的更好方法。也许sed -r 's~/([^/]*)$~_\1~'也可能合适,但我总是喜欢使用rev:)

由于find-sh c表达式的效果不佳,我们可以使用while循环:

while read -r file
do
    new_file=$(rev <<< "$file" | sed 's~/~_~' | rev)
    echo "mv $file $new_file"; done < <(find . -type f)
done < <(find . -type f)

作为一个单行:

while read -r file; do new_file=$(rev <<< "$file" | sed 's~/~_~' | rev); echo "mv $file $new_file"; done < <(find . -type f)

答案 1 :(得分:3)

这有点乏味但会做:

#!/bin/bash
parent=/parent
newfolder=/newfolder
mkdir "$newfolder"
for folder in "$parent"/*; do
  if [[ -d "$folder" ]]; then
    foldername="${folder##*/}"
    for file in "$parent"/"$foldername"/*; do
      filename="${file##*/}"
      newfilename="$foldername"_"$filename"
      cp "$file" "$newfolder"/"$newfilename"
    done
  fi
done

路径放到parent变量,将 newfolder 路径放到newfolder变量。