我想从我所在的父目录下的许多目录中移动大量文件。
我使用以下带有反引号的命令:
mv -t directory1/directory2/directory3/ `ls -R | grep _2_3`
所以我想将反引号中的命令源移动到目标目录“directory3”,该目录在我当前目录(父目录)下递归找到
有什么解决方案可以使用当前命令执行此操作吗?这个错误到底意味着什么?
答案1
你会注意到ls -R
输出文件名。也就是说,不输出路径名。因此,如果在您的子目录之一中找到名称中包含该字符串的文件_2_3
,则没有有关该字符串的信息在哪里ls -R
该文件可以在(与文件名同一行)的输出中找到。这会使您的命令失败(在当前目录中找不到文件名)。对于名称中包含空格、制表符或换行符的任何文件,它也会失败,并且如果任何文件名包含文件名通配字符,也可能会产生奇怪的结果。
相反,假设您想要移动文件名为结尾进入_2_3
一个目录/directory1/directory2/directory3
(并且该目录不是当前目录的子目录),然后
find . -type f -name '*_2_3' -exec mv -t /directory1/directory2/directory3 {} +
会那样做的。这将找到名称以_2_3
当前目录中或下的任何位置结尾的所有常规文件(不是目录或命名管道或符号链接等)的路径名,并且将mv -t /directory1/directory2/directory3
批量执行尽可能多的这些路径名。
在bash
shell 中,你也可以这样做
shopt -s globstar
mv -t /directory1/directory2/directory3 -- **/*_2_3
除非该模式扩展到数千个名称。 shellglobstar
选项bash
启用**
通配模式。它的工作原理类似于*
但会匹配穿过 /
在路径名中。因此,它将找到*_2_3
当前目录中或当前目录下任何位置匹配的所有名称。注意这个命令并不关心什么类型例如,名称匹配,并且也可能匹配目录名称(但您的ls -R
方法也会匹配)。
在zsh
shell 中,您可以更精确地匹配:
mv -t /directory1/directory2/directory3 -- **/*_2_3(.)
修改(.)
前面模式的行为以仅匹配常规文件。该**
模式在zsh
.
如果您想查找其名称的文件包含 _2_3
,然后只需将*_2_3
上述命令中文件名模式的位更改为*_2_3*
.
答案2
该消息的重要部分是:No such file or directory
。 ls -R
不包括文件路径。所以 mv
只有文件名,但找不到它,因为它的路径丢失。
改为这样做:
$ find . -name '*_2_3*' -exec mv -t directory1/directory2/directory3/ {} +
请注意,-exec … {} +
的操作find
符合 POSIX 标准,但mv -t
实际上并非如此。