我想再次詢問bash。 我想從目錄中隨機獲取文件。例如有如何在bash編程中從目錄中隨機獲取文件
13.525 file in 1 directory。
我是隨機的文件並獲取文件
gr123.adl併爲下一個隨機我想
gr123.adl不被再次選擇的文件。
我應該如何用bash語言實現它?
感謝對您的幫助之前
問候 Gustina MS
我想再次詢問bash。 我想從目錄中隨機獲取文件。例如有如何在bash編程中從目錄中隨機獲取文件
13.525 file in 1 directory。
我是隨機的文件並獲取文件
gr123.adl併爲下一個隨機我想
gr123.adl不被再次選擇的文件。
我應該如何用bash語言實現它?
感謝對您的幫助之前
問候 Gustina MS
你可以嘗試以下方法:
ls | sort -R | while read f; do echo $f; done
sort -R
被洗牌的文件中,while
循環確保你得到所有文件1由1
編輯:
如果某些文件中包含控制字符(如\n
),你可以試試這個:
OLDIFS=$IFS; IFS=$(echo -en "\b"); for f in $(ls -b | sort -R); do echo "$f"; done; IFS=$OLDIFS
這改變了輸入字段分隔符\b
(其更改爲適合任何沒有任何字符匹配所有文件名)。
ls -b
列出帶有控制字符的文件。
for
循環有一個接一個的文件。
最後,IFS
被設置爲其原始值。
請注意,如果有的話,這將無法正常工作文件的名稱中包含換行符 –
雖然我編輯了帖子以回答您的評論,但我認爲文件名中控制字符的處理方式值得自己去考慮。 – oliv
它經常是這裏討論的主題,並且出現了很多問題。他們通常會鏈接到http://mywiki.wooledge.org/ParsingLs和「不解析ls'的建議」 –
如果你真的想這樣做,那麼你需要一個函數,它會帶參數和跟蹤文件。
rand_file() {
track=~/${PWD##*/}.rand_file
touch $track
while read f; do
if ! grep -q "$f" $track; then
echo $f| tee -a $track
break
fi
done < <(ls |sort -R)
}
我們使用一個for循環,所以,如果我們已經得到了在目錄中的所有文件,它乾淨地退出。我們正在跟蹤以該目錄命名的文件,因此如果同名文件在別處,我們不會將它用作以前返回的文件 - 注意,這意味着您必須在PWD中使用它,您可以編寫一些代碼更好,但我現在不打算把這部分敲出來。一旦所有文件都被返回,函數退出並返回任何內容。您可以刪除主目錄中的文件以重置進程。
我可能會希望在另一種語言中做到這一點,如果可能的話,這種語言有更好的處理方式。例如,在python
你可以不喜歡它
files = os.listdir('.')
random.shuffle(files)
for path in files:
# do your code test stuff on path
具有將返回下一個文件名是強硬的bash
做的功能,但如果你只是想以隨機的順序對文件進行操作,我們可以遵循@ shelter的建議並使用數組,並結合在this answer中找到的隨機函數。在這裏,我們將打亂所有文件名中的數組,然後遍歷它們:
shuffle() {
local i tmp size max rand
# $RANDOM % (i+1) is biased because of the limited range of $RANDOM
# Compensate by using a range which is a multiple of the array size.
size=${#array[*]}
max=$((32768/size * size))
for ((i=size-1; i>0; i--)); do
while (((rand=$RANDOM) >= max)); do :; done
rand=$((rand % (i+1)))
tmp=${array[i]} array[i]=${array[rand]} array[rand]=$tmp
done
}
array=(*)
shuffle
for((i=0; i<${#array[*]}; i++)); do
printf "Operating on %s\n" "${array[i]}"
# do whatever test makes sense on "${array[i]}"
done
如果你真的想將返回「下一個」文件中的函數,我們可以從上面做到這一點有點不同,設置變量我們將用它來保存我們當前的文件名。因此,我們生病像這樣替換for循環在用另一個函數的定義和循環中的底部:
next_file() {
if [[ "$array_ind" -ge "${#array[*]}" ]]; then
cur=""
else
cur="${array[array_ind++]}"
fi
}
array_ind=0
# now we use next_file whenever we want `cur` to get the next file:
next_file
while [[ ! -z "$cur" ]]; do
printf -- "--%s--\n" "$cur"
next_file
done
我'MV文件dir_already_processed'爲你處理完一個文件,那麼你就無法再得到它。否則你必須維護一個列表(在一個文件或一個shell數組中)。祝你好運。 – shellter
這是一個現實世界的問題嗎?我想不出爲什麼你會需要這個?通常隨機在任何情況下都不是唯一的。 – SaintHax
@SaintHax我懷疑「測試」標記是這個用例的關鍵部分,我可以想象要編寫一個測試,以隨機的順序處理一個目錄中的文件 –