我有一项任务,我需要将一堆文件从一个目录移动到另一个目录。我需要同时移动所有具有相同文件名的文件(即blah.pdf,blah.txt,blah.html等等),我可以每四分钟移动一组这些文件。我有一个简短的bash脚本,只是按这些间隔一次移动一个文件,但是新的名称要求让我失望。
我的旧剧本是:
find ./ -maxdepth 1 -type f | while read line; do mv "$line" ~/target_dir/; echo "$line"; sleep 240; done
对于新脚本,我基本上只需要替换 find ./ -maxdepth 1 -type f
带有一个没有扩展名的唯一文件名列表。然后,我可以将do mv "$line" ~/target_dir/;
替换为do mv "$line*" ~/target_dir/;
。
所以,所有这些都说明了。使用bash脚本获取没有文件名的唯一文件列表的好方法是什么?我正在考虑使用正则表达式来获取文件名,然后将它们放入哈希中以获得唯一性,但我希望有更简单/更好/更快的方法。想法?
答案 0 :(得分:1)
一个奇怪命名的文件容忍单行可能是:
find . -maxdepth 1 -type f -and -iname 'blah*' -print0 | xargs -0 -I {} mv {} ~/target/dir
如果文件可以以多个前缀开头,则可以在find中使用逻辑运算符。例如,要移动blah。*和foo。*,请使用:
find . -maxdepth 1 -type f -and \( -iname 'blah.*' -or -iname 'foo.*' \) -print0 | xargs -0 -I {} mv {} ~/target/dir
评论后更新。
我是这样做的:
find ./ -type f -printf '%f\n' | sed 's/\..*//' | sort | uniq | ( while read filename ; do find . -type f -iname "$filename"'*' -exec mv {} /dest/dir \; ; sleep 240; done )
也许需要一些解释:
find ./ -type f -printf '%f\n':
查找所有文件并打印其名称,然后换行。如果您不想查看子目录,可以用简单的ls
; sed 's/\..*//'
:删除第一个点后的所有内容,以删除文件扩展名。 foo.tar
广告foo.tar.gz
都转化为foo
; sort | unique
:对找到的文件名进行排序并删除重复项; (
:打开子shell:
while read filename
:读取一行并将其放入$filename
变量; find . -type f -iname "$filename"'*' -exec mv {} /dest/dir \;
:在当前目录(find .
)中找到名称以-type f
(filename
中的值开头的所有文件(-iname "$filename"'*'
),这也适用于名称中包含空格的文件)并对每个文件执行mv
命令(-exec mv {} /dest/dir \;
)sleep 240
:sleep )
:子贝的结尾。根据您的要求,将-maxdepth 1
作为参数添加到find
。
答案 1 :(得分:0)
find ./ -maxdepth 1 -type f | sed -e 's/.[a-zA-Z]*$//' | uniq | while read line; do mv "$line*" ~/target_dir/; echo "$line"; sleep 240; done
编辑:在代码和反斜杠上忘记关闭标记。