2017-08-31 30 views
0

我想寫一個簡單的bash腳本,它隨機地從/music/文件夾中選擇.flac文件(它必須是遞歸的,因爲文件夾中有許多子文件夾該文件),並將該文件複製到/test/random.flac隨機選擇一個給定擴展名的文件並將其複製到給定的目錄

This post是非常接近我想要做的,但我不知道如何更改腳本來做我想做的。

我嘗試這樣做:

ls /music |sort -R |tail -1 |while read file; do 
    cp $file /test/random.flac 
done 

但我缺少如何告訴ls做遞歸搜索子文件夾內的所有.flac的。

+0

你到目前爲止試過了什麼?什麼導致您遇到困難,檢索文件或選擇隨機文件? – Verv

+0

@Verv我添加了我嘗試修改原始問題的腳本。謝謝 – Ignacio

回答

3

您可以將所有文件移入數組,然後在隨機索引處選擇一個移動。這需要globstar option啓用,所以你可以使用**/* glob模式:

shopt -s globstar 
flacfiles=(/music/**/*.flac) 
cp "${flacfiles[RANDOM % ${#flacfiles[@]}]}" /test/random.flac 

要選擇一個隨機指數,我們採取$RANDOM模的flacfiles數組中元素的個數。

如果你想的錯誤消息的情況下,水珠不匹配任何東西,你可以使用failglob外殼選項:

shopt -s globstar failglob 
if flacfiles=(/music/**/*.flac); then 
    cp "${flacfiles[RANDOM % ${#flacfiles[@]}]}" /test/random.flac 
fi 

這種失敗並顯示錯誤消息

-bash: no match: music/**/*.flac 

的情況下,沒有匹配的文件,並且不會嘗試複製任何內容。

如果您確定存在.flac文件,您可以忽略此項。

+1

@Inian我已經使用'failglob'添加了一個版本。 –

2

遞歸

使用find而不是ls

find /music/ -iname '*.flac' -print0 | shuf -z -n1 

find一部分會發現目錄裏面/music/所有FLAC文件,並列出它們。
shuf洗牌列表和打印第一個條目(隨機,因爲列表被洗牌)。

-print0-z是否使用\NUL來分隔文件名。沒有這些選項,將會使用\n(換行符),這是不安全的,因爲文件名可以包含換行符(即使它很少見)。

複製

如果你想複製只有一個隨機文件,沒有必要爲一個while循環。改爲使用替代$()

cp "$(find /music/ -iname '*.flac' -print0 | shuf -z -n1)" /test/random.flac 
相關問題