如何在bash中列出没有扩展名的所有唯一文件名?

时间:2010-10-08 21:25:58

标签: bash

我有一项任务,我需要将一堆文件从一个目录移动到另一个目录。我需要同时移动所有具有相同文件名的文件(即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脚本获取没有文件名的唯一文件列表的好方法是什么?我正在考虑使用正则表达式来获取文件名,然后将它们放入哈希中以获得唯一性,但我希望有更简单/更好/更快的方法。想法?

2 个答案:

答案 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 ffilename中的值开头的所有文件(-iname "$filename"'*'),这也适用于名称中包含空格的文件)并对每个文件执行mv命令(-exec mv {} /dest/dir \;
    • sleep 240:sleep
  • ):子贝的结尾。

根据您的要求,将-maxdepth 1作为参数添加到find

答案 1 :(得分:0)

没关系,我很笨。有一个uniq命令。咄。新的工作脚本是:

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

编辑:在代码和反斜杠上忘记关闭标记。