【问题标题】:How to make a FOR loop to move files to directory based on file extension如何制作 FOR 循环以根据文件扩展名将文件移动到目录
【发布时间】:2021-12-26 02:06:54
【问题描述】:

我正在尝试对数千个文件进行排序,并根据文件扩展名将它们放在自己的文件夹中。例如,将 JPG 文件放入 JPG 文件夹。

如何创建一个 for 循环来解决这个问题?

我尝试过的事情:

# This listed out all the file extensions and the count for each extension:
find . -type f | rev | cut -d. -f1 | rev  | tr '[:upper:]' '[:lower:]' | sort | uniq --count | sort -rn
#This was able to find all jpegs in the media folder
find /media -iname '*.jpg' 
# This worked, however the MV command does not create the folder
find /media -iname '*.jpg' -exec mv '{}' /media/genesis/Passport/consolidated/jpg/ \; # 

我猜测 for 循环会是这样的,但我似乎无法弄清楚:

for dir in 'find /media -iname "*.jpg"'; do
    mkdir $dir;
    mv $dir/*;
done

【问题讨论】:

  • /media中有多少级目录?可以使用find,但是如果您要递归查找并移动到单个目录,则必须决定如何处理重复的文件名。特别是如果有很多DSC_0001.JPG。还有exiftool,可以根据图片的元数据创建文件和目录命名方案。
  • 在你的循环中检查 'echo ${dir##*/};回声 ${dir%/*}'
  • @dan 文件夹只有一层,但大约有 100 个文件夹。每个大约有 500-600 个文件。 (我不得不恢复一个分区被擦除的媒体硬盘驱动器,并且文件结构没有得到维护)
  • 如果你使用rename,也称为Perl renameprename,你会有几个好处1)你不需要循环,2)你不需要创建输出目录,因为它为您制作,3) 您可以进行 “试运行”,4) 您可以使用 Perl 正则表达式的强大功能来提取、小写和修改文件名和 5 ) 如果您将 1.jpg 从两个不同的目录移动到一个共同的目标位置,它不会破坏文件。

标签: linux bash shell scripting


【解决方案1】:

你可以试试这个脚本。

应该找到/media中的所有文件并将其移动到pwd中具有类似扩展名的目录。

$ cat locate.sh
#!/usr/bin/env bash

for files in $(find /media -type f); do 
    dir=$(echo "$files" | sed 's/.[^.]*.\(.*\)/\1/g')  
    loc_path=$(pwd)/"$dir" 
    if [[ ! -d "$loc_path" ]]; then 
        mkdir "$loc_path" &>/dev/null 
        mv "$files" "$loc_path"
    else
        mv "$files" "$loc_path"
    fi
done

注意:请在使用实际数据之前进行测试。

【讨论】:

  • 将中断带有空格的文件名。考虑带有(gnu)NUL终止符的find-while-read循环
【解决方案2】:

要查找特定扩展名的所有文件并将其移动到目标,我们可以使用find 命令,如下所示:

find . -name "*.jpg" -exec mv {} $destination/ \;

这是关键逻辑,您可以在此基础上创建一个 for 循环来遍历媒体文件夹中所有已知的文件扩展名

## List all the known extensions in your media folder.
declare -a arr=("jpg" "png" "svg")

## Refer question 1842254 to get all the extentsions in your folder.
## find . -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u


## now loop through the above array
for i in "${arr[@]}"
do
   echo "$i"
   ## Create a directory based on file extension
   destination="$i"
   mkdir $destination
   find /media -iname "*.$i" -exec mv {} $destination/ \;
done

请注意,您可以将目的地更改为任何您想要的。我只是把它放在同一个目录中。

这是一个可执行的 shell 脚本供您参考:https://onlinegdb.com/NEQSpojhM

【讨论】:

  • 这会将整个磁盘运行 3 次。它不会找到 JPG
  • 您可以使用-iname 标志和find 命令使其不区分大小写。至于运行磁盘三次,我冒昧地认为它不是最佳的,因为这只是一次工作:)
  • 是的,OP 就是这样做的。您不应该回答我的 cmets,而是编辑您的答案以避免被否决。考虑optimizing您的非最佳代码;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-03
  • 2019-09-13
  • 2014-06-06
  • 1970-01-01
  • 1970-01-01
  • 2013-08-03
相关资源
最近更新 更多