Reputation: 308
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
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