2010-10-08 22 views
3

使用示例(人爲!):將.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}語法?

+0

你問一個沒有純粹答案的問題。或者至少你願意接受的答案,因爲你從未檢查過接受。我的'hackish'的方式,是管道'find ... | sed ... | xargs ...'。你說的是你的替代方法。所以爲了清楚地分解它,'xargs'本身不支持Bash變量擴展。你能解決這個問題,在許多不同的方法?如你所知,是的!你可以在'xargs'中'純粹'嗎?沒有! – TechZilla 2012-11-02 17:19:41

回答

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 
+1

我知道如何做到這一點;這個問題的目的是看看是否可以用xargs做到這一點,並讓它不會立即展開replace-str(我猜)。 – user428502 2010-10-08 14:50:45

2

不,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" 
+0

在xargs做什麼之前,有任何方法讓shell擴展表達式? – user428502 2010-10-08 15:07:48

+0

「bash」的原因是它被解釋爲$ 0,所以$ 1變成xargs饋入的內容。 – momeara 2012-08-31 21:30:41

1

如果你有GNU並行安裝:

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

如果你的文件名稱中不包含\ n(新行),這將工作太:

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

觀看介紹視頻以瞭解更多關於GNU並行的信息http://www.youtube.com/watch?v=OpaiGYxkSuQ

1

只是添加另一個建議,即使它不使用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)

+0

好'while ... do; ...完成<<(find)'? – fedorqui 2015-12-01 13:43:03

+1

對於當代Bash,當然。但它不能移植回真正老的Bash版本,這裏的OP可能會受到影響,所以我試圖使這種合理的便攜式。即使在傳家寶'sh'和其他類似的外殼中,這也應該可以工作。 – tripleee 2015-12-02 05:16:26