假设我有多个随机的`.txt`文件,并且在同一个目录下,我有几乎相同名称的文件,如`filename.sql`和`filename.txt`。如何找到这些`.sql`及其对应的`.txt`文件,而不选择任何其他`.txt`文件?(意图是将它们移动到单独的文件夹中。这里保证了相关`.sql`和`.txt`文件之间存在1:1的关系,因此我不担心移动最初提到的任何随机`.txt`文件之一。)
$ mv `ls *.sql|sed s/.sql$/.txt/g` dir
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
piokuc的答案非常好,但如果你遇到参数列表太长的错误 (如果你一次移动很多文件时会发生),这个方法也可以解决问题:
ls *.sql | sed s/.sql/.txt/g | xargs -I% mv % /path/to/new/directory
解释:
.sql
扩展名结尾的文件名。.txt
替换.sql
(这不会重命名文件,只是对管道输入进行操作)。xargs
xargs
是一个运行其他程序的程序。我们将通过它来运行mv
(移动文件)命令。-I
选项告诉xargs
为每个由sed
传递的单个文件名运行mv
命令。%
是指实际对象/文件名被传递给xargs
,因此在每次迭代中,这将是一个替换后的文件名之一。%
:一个附加在-I
旁边,它告诉xargs
使用和号字符作为文件名的标记。第二次出现在mv
中,其中实际(并且现在已更改)的文件名被替换为令牌。基本上,xargs
的意思是,“对于输入的每个文件名,运行mv NEW_FILE_NAME.txt /path/to/new/directory
。”
for f in *.sql; do mv
echo $f|sed s/.sql$/txt/ dir; done
- piokuc
.sql
替换为.txt
并将文件移动到dir
目录。 - piokuc.sql
替换为.txt
),请使用s/.sql$/.txt/
。由于来自ls
的每个文件名都将位于其自己的行上,因此替换末尾的g
是不必要的。 - Lorkenpeistsed
不会修改文件名,它只会修改ls
提供的输出。因此,当ls
打印foo.sql
时,sed 会使其打印foo.txt
,以便mv
可以移动正确的文件。 - Lorkenpeistecho
命令,观察 shell 如何展开它。 - piokuc