如何查找仅通过扩展名区分的文件

时间:2013-05-22 21:09:41

标签: shell unix

假设我有多个随机.txt文件,并且在同一目录中我有几乎同名的文件,如filename.sqlfilename.txt。如何在不选择任何其他.sql文件的情况下找到这些.txt及其对应的.txt文件? (这里的目的是将它们移动到一个单独的文件夹。相关的.sql.txt文件之间保持1:1的关系,这意味着我不担心移动其中一个最初提到的随机.txt文件。)

2 个答案:

答案 0 :(得分:3)

很简单:

$ mv `ls *.sql|sed s/.sql$/.txt/g` dir

要查看并了解其工作原理,shell在执行mv之前如何扩展该行,请使用echo开始行:

$ ls
a.sql b.sql a.txt b.txt c.txt
$ echo mv `ls *.sql|sed s/.sql/.txt/g` dir
mv a.txt b.txt dir

如果文件名有空格(在Unix中通常不是一个好主意,但发生了),或者你在目录中有数百个文件,那就更“健壮”了:

$ for f in *.sql; do mv "$(echo $f|sed s/.sql$/txt/)" dir; done

.sql文件与相应的.txt文件一起移动:

$ for f in *.sql; do mv "$f" "$(echo $f|sed s/.sql$/txt/)" dir; done

答案 1 :(得分:2)

piokuc的答案效果很好,但是如果你的 参数列表太长 错误(如果你一次移动很多文件就会发生),这就像好:

ls *.sql | sed s/.sql/.txt/g | xargs -I% mv % /path/to/new/directory

说明:

  1. 列出以.sql扩展名结尾的所有文件名。
  2. .sql替换为文件名列表中的.txt(这不会重命名文件,只需对管道输入进行操作)。
  3. xargs

    • xargs是一个运行其他程序的程序。我们将通过它运行mv(移动文件)命令。
    • -I选项告诉xargs分别为mv传递的每个文件名运行sed命令。
    • %是指传递给xargs的实际对象/文件名,因此在每次迭代时,这将是替换文件名之一。
    • 请注意,有两个%:一个附加在-I旁边,它告诉xargs使用&符号作为文件名的标记。第二次出现在mv,其中实际(现在已更改)文件名替换为令牌。

    基本上,xargs说,“对于每个管道输入的文件名,请运行mv NEW_FILE_NAME.txt /path/to/new/directory。”