davidt
davidt

Reputation: 308

Move Files X Per Folder

I've put a script together that moves a predefined number of files into folders that are created sequentially. It seems somewhat sluggish and being new to this I'm wondering if there's a more elegant do shell script command to aid in this.

set filesPerFolder to 100
set zeroPad to 3

tell application "Finder" to set chosenFolder to (target of Finder window 1) as text

set thisDir to POSIX path of chosenFolder
set folderCount to 1

repeat
    set folderCount to zero_pad(folderCount, zeroPad)
    set filesToMove to (do shell script "ls -1 " & thisDir & " | wc -l") as integer

    if filesToMove is 0 then
        return
    end if

    set theNewFolder to thisDir & folderCount
    set asDir to POSIX file theNewFolder

    tell application "Finder"
        if exists asDir then
            -- do nothing
        else
            do shell script "mkdir -p " & theNewFolder
        end if
    end tell

    tell application "Finder" to set firstFile to first file of folder chosenFolder as alias
    set fileToMove to POSIX path of firstFile
    set theMove to quoted form of fileToMove & " '" & theNewFolder & "/'"
    do shell script "mv -f " & theMove

    set filesInFolder to (do shell script "ls -1 " & theNewFolder & " | wc -l") as integer

    if filesInFolder ≥ 10 then
        set folderCount to folderCount + 1
    end if
end repeat

on zero_pad(value, string_length)
    set string_zeroes to ""
    set digits_to_pad to string_length - (length of (value as string))
    if digits_to_pad > 0 then
        repeat digits_to_pad times
            set string_zeroes to string_zeroes & "0" as string
        end repeat
    end if
    set padded_value to string_zeroes & value as string
    return padded_value
end zero_pad

Thanks to Lri's shell command the script is leaner and efficient.

tell application "Finder" to set thisDir to (target of Finder window 1) as string
set rootDirectory to quoted form of POSIX path of thisDir
set counTed to (do shell script "ls -1 " & rootDirectory & " | wc -l") as integer
set filesToMove to (do shell script "ls -2 " & rootDirectory & " | wc -l") as integer
if filesToMove is 0 then
display alert "There are no files in the root of this directory to move."
return
end if
set filesPerFolder to text returned of (display dialog "There are " & counTed & " files     in this folder. 
How many files would you like to move per folder: " default answer "100")
set fileCount to (do shell script "cd " & rootDirectory & " && i=0;for f in *;do    d=$(printf %03d $((i/" & filesPerFolder & "+1)));let i++;mkdir -p $d;mv \"$f\" $d;done")
set filesLeft to (do shell script "ls -2 " & rootDirectory & " | wc -l") as integer
if filesLeft is 0 then
display alert "Completed."
return
end if

Upvotes: 1

Views: 154

Answers (1)

Lri
Lri

Reputation: 27623

i=0;for f in *;do d=$(printf %03d $((i/100+1)));let i++;mkdir -p $d;mv "$f" $d;done

Or using GNU parallel:

ls|parallel -k -N100 x=\$\(printf %03d {#}\)\;mkdir -p \$x\;mv {} \$x

-k keeps the order of the lines and {#} is the sequence number.

Upvotes: 2

Related Questions