3

使用示例(人为!):将 .mp3 文件重命名为 .txt。

我希望能够做类似的事情

find -name '*.mp3' -print0 | xargs -0 -I'file' mv file ${file%.mp3}.txt

这不起作用,所以我使用了 pipefind的输出 through sed -e 's/.mp3//g',这可以解决问题。

不过似乎有点骇人听闻;有没有办法使用通常的 bash${x%y}语法?

4

5 回答 5

2

不,xargs -0 -I'file' mv file ${file%.mp3}.txt不会起作用,因为该file变量将由 xargs 程序而不是 shell 扩展。实际上将其称为变量并不完全正确,在xargs的手册中称为“replace-str”。

更新:要只使用 xargs 和 bash (而不是 sed 或类似的),你当然可以让 xargs 启动一个 bash 进程,然后可以做任何你想要的替换:

find -name '*.mp3' -print0 | xargs -0 bash -c \
'while [ -n "$1" ]; do mv "$1" "${1%.mp3}.txt" ; shift; done;' "bash"
于 2010-10-08T14:48:58.783 回答
1

只是添加另一个建议,即使它不使用 shell 的替换机制,而是使用 sed 的。

find -name '*.mp3' -print |
sed -e 's/\.mp3$//' -e "s/.*/mv '&\.mp3' '&\.txt'/" |
sh

换句话说,mv为每个文件名创建一个命令行,并将结果传递给sh.

如果任何文件的文件名中有撇号(单引号),这将失败。我主要发布这个来对抗“如果你只有 xargs,每个问题都会看起来像钉子”综合症。

并非所有 sed 都具有完全相同的语法。特别是,我不能 100% 确定您可以在一些笨拙的旧 SunOS 上使用多个 -e 参数(在类似的内容中查找与 XPG 兼容的 sed /usr/ucb/blah/barf/vomit/xpg4/bin/sed

于 2011-08-05T04:22:50.480 回答
1

如果您安装了 GNU Parallel:

find -name '*.mp3' -print0 | parallel -0 mv {} {.}.txt

如果您的文件名不包含 \n (换行符),这也可以:

find -name '*.mp3' | parallel mv {} {.}.txt

观看介绍视频以了解有关 GNU Parallel 的更多信息http://www.youtube.com/watch?v=OpaiGYxkSuQ

于 2010-10-08T23:04:14.960 回答
0
find . -type f -name '*.mp3' | while read -r F
do
  mv "$F" "${F%.mp3}.txt"
done

重击 4+

shopt -s globstar
shopt -s nullglob
for file in **/*.mp3
do
    mv "$file" "${file%.mp3}.txt"
done
于 2010-10-08T14:44:45.727 回答
0
perl rename.pl 's/\.mp3$/.txt/' *.mp3  
# Or **/*.mp3 for zsh and bash with specific settings set, for a recursive 
# rename.

http://people.sc.fsu.edu/~jburkardt/pl_src/rename/rename.html

于 2012-05-29T19:45:38.693 回答