2

试图重命名 linux 服务器上的一系列文件。找到我想要的文件很容易:

find . -type f -wholename \*.mbox

当然,作为 mbox 文件,其中一些名称中带有空格,因此变为:

find . -type f -wholename \*.mbox -print0

我正在传输到 xargs 以便我可以重命名文件:

find . -type f -wholename \*.mbox -print0 | xargs -0 -I{} echo ${"{}"/.mbox/}

鉴于 INBOX.mbox,回声应该返回类似于 INBOX 的内容,但是 bash 抱怨:

bash: ${"{}"/.mbox/}: bad substitution

我怎样才能解决这个问题?如果可能的话,我想尝试将它保存在 find/xargs 解决方案中,这样我就不会在它周围添加很多循环结构。

4

6 回答 6

8

尝试

find . -type f -wholename \*.mbox | sed 's/\(.*\)\.mbox/mv "\1.mbox" "\1"/' | sh

如果某些文件包含双引号字符,这不是 100% 万无一失的,但我认为您可以忽略它:)

于 2009-05-06T18:17:43.927 回答
2

GNU Parallel http://www.gnu.org/software/parallel/有 {.} 删除扩展:

find . -type f -wholename \*.mbox -print0 | parallel -0 mv {} {.}

如果您知道文件名不包含 \n 那么这也可以:

find . -type f -wholename \*.mbox | parallel mv {} {.}
于 2010-06-10T18:55:05.130 回答
1

你可以试试:

find . -type f -wholename \*.mbox -print0 | sed 's/\.mbox//'

您的问题是试图通过管道输入 xargs。到那时"{}"已经没有任何意义了。

重命名文件(假设您在 bash 下)

find . -type f -wholename \*.mbox -print0 | \
    while read I ; do
        mv $I $(echo $I | sed 's/\.mbox//') ;
    done ;
于 2009-05-06T14:58:14.530 回答
1

我认为你需要这个:

find . -wholename \*.mbox | awk '{new=$0; gsub("\.mbox$", "", new) ; system("mv \"" $0 "\" \"" new "\"") }'

(应该同时兼容 gawk 和 mawk,在 mawk 上测试)。它不使用 xargs,但请注意,它不会为每个移动的文件派生一个新进程。如果您需要移动大量文件,您会发现其优势。警告:如果任何文件的名称中包含换行符,你会遇到麻烦(但如果这是一个问题,上帝与你同在)。

您可以通过使用 xargs 在一次rm调用中删除多个文件来进一步增强此解决方案。

如果您真的需要速度,我建议您使用 python 脚本而不是 awk。这将在rm没有一个叉子的情况下完成所有操作。

于 2009-05-06T19:09:17.390 回答
1

你可以使用重命名(1)吗?它带有 perl。

于 2009-05-06T19:49:04.377 回答
0

给你,这应该可以解决问题....

# find .
.
./test.tst
./test1.tst
./test2.tst
./test/test4.tst
./test/test5.tst

#

for file in `find . -type f`
do
mv $file ${file%.tst}.new
done

# find .
.
./test
./test/test4.new
./test/test5.new
./test1.new
./test2.new
于 2010-03-02T15:47:41.317 回答