0

我的问题是我在单个目录中有太多文件。我不能“ ls”目录,因为太大了。我需要将所有文件移动到更好的目录结构中。

我以相反的方式使用 ID 中的最后 3 位数字作为文件夹。

例如 ID2018972必须进入/2/7/9/img_2018972.jpg

我已经创建了目录,但现在我需要 bash 脚本的帮助。我知道 ID,在范围内1,300,000 - 2,000,000。但我无法处理正则表达式。

我不想像这样移动所有文件:

/images/folder/img_2018972.jpg -> /images/2/7/9/img_2018972.jpg

我将不胜感激有关此主题的任何帮助。谢谢!

4

2 回答 2

1

编辑:在评论中解释后,存在以下假设:

  • 文件名的形式为img_<id>.jpgimg_<id>_<size>.jpg
  • 新目录是id的最后三个数字的相反顺序

使用 Bash:

for file in /images/folder/*.jpg; do 
    fname="${file%.*}"      # remove extension and _<size>
    [[ "$fname" =~ img_[0-9]+_[0-9]+$ ]] && fname="${fname%_*}"

    last0="${fname: -1:1}"  # last letter/digit
    last1="${fname: -2:1}"  # last but one letter/digit
    last2="${fname: -3:1}"  # last but two letter/digit

    newdir="/images/$last0/$last1/$last2"
    # optionally check if the new dir exists, if not create it
    [[ -d "$newdir" ]] || mkdir -p "$newdir"

    mv "$file" "$newdir"
done

如果*无法处理(尽管我认为*在 for 循环中没有限制),请按照@Michał Kosmulski 在评论中的建议
使用find

while read -r; do 
    fname="${REPLY%.*}"     # remove extension and _<size>
    [[ "$fname" =~ img_[0-9]+_[0-9]+$ ]] && fname="${fname%_*}"

    last0="${fname: -1:1}"  # last letter/digit
    last1="${fname: -2:1}"  # last but one letter/digit
    last2="${fname: -3:1}"  # last but two letter/digit

    newdir="/images/$last0/$last1/$last2"
    # optionally check if the new dir exists, if not create it
    [[ -d "$newdir" ]] || mkdir -p "$newdir"

    mv "$REPLY" "$newdir"
done < <(find /images/folder/ -maxdepth 1 -type f -name "*.jpg")
于 2012-04-16T10:24:31.150 回答
1
find /images/folder -type f -maxdepth 1 | while read file
do
filelen=${#file}
((rootn=$filelen-5))
((midn=$filelen-6))
((topn=$filelen-7))
root=${file:$rootn:1}
mid=${file:$midn:1}
top=${file:$topn:1}
mkdir -p /images/${root}/${mid}/${top}
mv $file /images/${root}/${mid}/${top}
done
于 2012-04-16T10:47:30.153 回答