xargs
我正在尝试通过运行以下命令来重命名子目录中的文件:
find . -name oldfile.txt -print0 | xargs -n 1 -0 -I % mv % newfile.txt
问题是文件被移动到我运行命令的目录中,而不是oldfile.txt
找到的目录中。我似乎无法解决这个问题,有什么想法吗?
我在想也许我可以从找到的文件的路径中获取目录,然后将其附加到第二个参数的前面,mv
但是这该如何工作呢?
答案1
find
您可以使用's ,而不必依赖外部命令,因为这样会丢失有关当前目录的信息-execdir
选项让它在文件所在的目录中执行命令。
find . -name oldfile.txt -execdir mv -- {} newfile.txt \;
这实际上是更安全的版本,-exec
在大多数情况下是首选。唯一的缺点是它不是由 POSIX 指定的,因此您不会在所有find
变体中找到它 - 但至少在 GNUfind
和 BSD中find
可以找到它。
如果您想要更加安全,您应该调用mv
类似的mv -- source target
方法,以便以破折号开头的文件不会被错误地解释为的参数mv
。
如果由于某种原因您不想使用-execdir
或不想做其他复杂的事情,或者只是想了解一点有关 Bash 的知识,那么下面是如何获取文件夹并基于此移动文件的方法:
find . -name oldfile.txt -exec bash -c 'mv -- "${0}" "$(dirname $0)"/newfile.txt' {} \;
这里,{}
将完整路径传递给bash
as $0
。我们通过命令替换 ( $(…)
) 获取其目录名称,然后附加新名称。原始参数和目录名称都必须用双引号引起来,以防止空格破坏命令 - 否则mv
会认为您正在尝试移动两个名为 和 的文件foo
,而bar
实际上该文件名为foo bar
,例如。