5

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

4

2 回答 2

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
于 2013-05-22T21:18:18.427 回答
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运行命令。mvsed
    • %指传递给的实际对象/文件名xargs,因此在每次迭代时,这将是替换的文件名之一。
    • 请注意,有 2 %: 一个附加在 旁边-I,它告诉xargs使用 & 字符作为文件名的标记。第二次出现是 with mv,其中实际(并且现在已更改)文件名被替换为令牌。

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

于 2013-05-22T21:22:42.450 回答