如何在多个不同目录中移动多个文件(在Linux上)
我的问题是我在单个目录中有太多文件。我不能“ls
”这个目录,cos太大。我需要移动更好的目录结构中的所有文件。如何在多个不同目录中移动多个文件(在Linux上)
我以相反方式使用来自ID的最后3位数字作为文件夹。
例如ID 2018972
必须在/2/7/9/img_2018972.jpg
去。
我已经创建了目录,但现在我需要帮助bash脚本。我知道这些ID,范围1,300,000 - 2,000,000
。但我无法处理正则表达式。
我wan't将所有的文件是这样的:
/images/folder/img_2018972.jpg -> /images/2/7/9/img_2018972.jpg
我会很高兴在这个问题上的任何帮助。谢谢!
编辑:在注释中解释相关后,以下假设存在:
- 文件名是在
img_<id>.jpg
或img_<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循环中没有限制),
使用find
作为意见提出由@米哈尔Kosmulski
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")
由于文件数量庞大,'/ images/folder/*。jpg'的shell扩展可能无法工作,但是您可以用'find/images/folder -maxdepth 1 -type f -name替换for循环'* .jpg'|同时阅读;做做东西;完成' – 2012-04-16 10:34:39
添加了该选项,但我认为'*'在循环中使用时没有限制。当用作函数/脚本的参数时有限制;那是'ARG_MAX'。 – c00kiemon5ter 2012-04-16 10:42:58
感谢您的帮助。我使用了脚本的第二个版本(我们在评论中使用了@MichałKosmulski的建议)。它工作的很好,即使在文件夹中他们是如此多的文件,我甚至不能算......我想有超过2-3百万个文件。让我们看看它何时完成。感谢大家的帮助! – Alex 2012-04-16 12:25:24
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
我认为这是计算偏移量过多的工作。在UNIX和UNIX等操作系统中,也允许文件名包含任何内容。你最好在那里添加一些引号,并查看'-r'开关到'read'。尝试在你的shell中“帮助阅读”;) – c00kiemon5ter 2012-04-16 10:52:00
你可以使用类似的东西来模拟'ls'; '为f in *;做printf - “%s \ t”“$ f”;完成'和'ls -1'与'for f in *;做printf - “%s \ n”“$ f”;完成'。 'ls'因为'ARG_MAX',最大参数限制而失败。 – c00kiemon5ter 2012-04-16 10:47:48
感谢重播,我忘了提及,在文件夹中我有更多的jpg文件具有相同的文件名结构,但在结尾处有“_220,_380”..如:img_1234567_220.jpg。 – Alex 2012-04-16 11:00:00
你的意思是说你不想匹配那些?或者答案没问题? – c00kiemon5ter 2012-04-16 11:03:41