2012-04-16 70 views
0

我的問題是我在單個目錄中有太多文件。我不能「ls」這個目錄,cos太大。我需要移動更好的目錄結構中的所有文件。如何在多個不同目錄中移動多個文件(在Linux上)

我以相反方式使用來自ID的最後3位數字作爲文件夾。

例如ID 2018972必須在/2/7/9/img_2018972.jpg去。

我已經創建了目錄,但現在我需要幫助bash腳本。我知道這些ID,範圍1,300,000 - 2,000,000。但我無法處理正則表達式。

我wan't將所有的文件是這樣的:

/images/folder/img_2018972.jpg -> /images/2/7/9/img_2018972.jpg 

我會很高興在這個問題上的任何幫助。謝謝!

+0

你可以使用類似的東西來模擬'ls'; '爲f in *;做printf - 「%s \ t」「$ f」;完成'和'ls -1'與'for f in *;做printf - 「%s \ n」「$ f」;完成'。 'ls'因爲'ARG_MAX',最大參數限制而失敗。 – c00kiemon5ter 2012-04-16 10:47:48

+0

感謝重播,我忘了提及,在文件夾中我有更多的jpg文件具有相同的文件名結構,但在結尾處有「_220,_380」..如:img_1234567_220.jpg。 – Alex 2012-04-16 11:00:00

+0

你的意思是說你不想匹配那些?或者答案沒問題? – c00kiemon5ter 2012-04-16 11:03:41

回答

1

編輯:在註釋中解釋相關後,以下假設存在:

  • 文件名是在img_<id>.jpgimg_<id>_<size>.jpg
  • 形式新的目錄是反向順序的最後三個數字ID

使用Bash:

for file in /images/folder/*.jpg; do 
    fname="${file%.*}"  # remove extension and _<size> 
    [[ "$fname" =~ img_[0-9]+_[0-9]+$ ]] && fname="${fname%_*}" 

    last0="${fname: -1:1}" # last letter/digit 
    last1="${fname: -2:1}" # last but one letter/digit 
    last2="${fname: -3:1}" # last but two letter/digit 

    newdir="/images/$last0/$last1/$last2" 
    # optionally check if the new dir exists, if not create it 
    [[ -d "$newdir" ]] || mkdir -p "$newdir" 

    mv "$file" "$newdir" 
done 

如果*不能處理它(雖然我覺得*在for循環中沒有限制),
使用find作爲意見提出由@米哈爾Kosmulski

while read -r; do 
    fname="${REPLY%.*}"  # remove extension and _<size> 
    [[ "$fname" =~ img_[0-9]+_[0-9]+$ ]] && fname="${fname%_*}" 

    last0="${fname: -1:1}" # last letter/digit 
    last1="${fname: -2:1}" # last but one letter/digit 
    last2="${fname: -3:1}" # last but two letter/digit 

    newdir="/images/$last0/$last1/$last2" 
    # optionally check if the new dir exists, if not create it 
    [[ -d "$newdir" ]] || mkdir -p "$newdir" 

    mv "$REPLY" "$newdir" 
done < <(find /images/folder/ -maxdepth 1 -type f -name "*.jpg") 
+0

由於文件數量龐大,'/ images/folder/*。jpg'的shell擴展可能無法工作,但是您可以用'find/images/folder -maxdepth 1 -type f -name替換for循環'* .jpg'|同時閱讀;做<根據$ REPLY>做東西;完成' – 2012-04-16 10:34:39

+0

添加了該選項,但我認爲'*'在循環中使用時沒有限制。當用作函數/腳本的參數時有限制;那是'ARG_MAX'。 – c00kiemon5ter 2012-04-16 10:42:58

+0

感謝您的幫助。我使用了腳本的第二個版本(我們在評論中使用了@MichałKosmulski的建議)。它工作的很好,即使在文件夾中他們是如此多的文件,我甚至不能算......我想有超過2-3百萬個文件。讓我們看看它何時完成。感謝大家的幫助! – Alex 2012-04-16 12:25:24

0
find /images/folder -type f -maxdepth 1 | while read file 
do 
filelen=${#file} 
((rootn=$filelen-5)) 
((midn=$filelen-6)) 
((topn=$filelen-7)) 
root=${file:$rootn:1} 
mid=${file:$midn:1} 
top=${file:$topn:1} 
mkdir -p /images/${root}/${mid}/${top} 
mv $file /images/${root}/${mid}/${top} 
done 
+0

我認爲這是計算偏移量過多的工作。在UNIX和UNIX等操作系統中,也允許文件名包含任何內容。你最好在那裏添加一些引號,並查看'-r'開關到'read'。嘗試在你的shell中「幫助閱讀」;) – c00kiemon5ter 2012-04-16 10:52:00

相關問題