使用示例(人爲!):將.mp3文件重命名爲.txt。
我希望能夠做到像
find -name '*.mp3' -print0 | xargs -0 -I'file' mv file ${file%.mp3}.txt
這是不行的,所以我使出管道通過sed -e 's/.mp3//g'
find
的輸出,這是卓有成效的。
雖然似乎有點hackish; 有沒有辦法使用通常的bash ${x%y}
語法?
使用示例(人爲!):將.mp3文件重命名爲.txt。
我希望能夠做到像
find -name '*.mp3' -print0 | xargs -0 -I'file' mv file ${file%.mp3}.txt
這是不行的,所以我使出管道通過sed -e 's/.mp3//g'
find
的輸出,這是卓有成效的。
雖然似乎有點hackish; 有沒有辦法使用通常的bash ${x%y}
語法?
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
我知道如何做到這一點;這個問題的目的是看看是否可以用xargs做到這一點,並讓它不會立即展開replace-str(我猜)。 – user428502 2010-10-08 14:50:45
不,xargs -0 -I'file' mv file ${file%.mp3}.txt
將不能工作,因爲file
變量將由xargs的程序,而不是外殼擴展。其實把它作爲一個變量是不正確的,它在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"
在xargs做什麼之前,有任何方法讓shell擴展表達式? – user428502 2010-10-08 15:07:48
「bash」的原因是它被解釋爲$ 0,所以$ 1變成xargs饋入的內容。 – momeara 2012-08-31 21:30:41
如果你有GNU並行安裝:
find -name '*.mp3' -print0 | parallel -0 mv {} {.}.txt
如果你的文件名稱中不包含\ n(新行),這將工作太:
find -name '*.mp3' | parallel mv {} {.}.txt
觀看介紹視頻以瞭解更多關於GNU並行的信息http://www.youtube.com/watch?v=OpaiGYxkSuQ
只是添加另一個建議,即使它不使用shell的替代機制,而是使用sed's。
find -name '*.mp3' -print |
sed -e 's/\.mp3$//' -e "s/.*/mv '&\.mp3' '&\.txt'/" |
sh
換言之,創建用於每個文件名的mv
命令行,並且將結果傳遞給sh
。
如果任何文件的文件名中有撇號(單引號),將會失敗。我主要張貼這個來對付「如果你有全部是xargs,每個問題都會看起來像釘子」綜合徵。
並非所有的seds都有完全相同的語法。特別是,我不是100%肯定,你可以有一些這些混沌舊的SunOS多個-e參數(尋找XPG兼容的類似/usr/ucb/blah/barf/vomit/xpg4/bin/sed
SED)
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
你問一個沒有純粹答案的問題。或者至少你願意接受的答案,因爲你從未檢查過接受。我的'hackish'的方式,是管道'find ... | sed ... | xargs ...'。你說的是你的替代方法。所以爲了清楚地分解它,'xargs'本身不支持Bash變量擴展。你能解決這個問題,在許多不同的方法?如你所知,是的!你可以在'xargs'中'純粹'嗎?沒有! – TechZilla 2012-11-02 17:19:41