16

I've got 291 numbered files (starting at 001 - title and ending at 291 - title) that need moved into separate directories. (001 to 021 to folder 1, 022 to 053 to folder 2, they aren't necessarily the same number of files each time).

I figured I could do it in a yucky way like this: ls | head -n 21 | sed -r 's|(.*)|mv \1 /path/to/folder1|' | sh

I'm almost positive there's a better way, so what would it be?

EDIT: So that would've worked fine, but I remembered...

I'm not stuck using a terminal, so I used a file manager to click and drag. Question still stands though.

Rob
  • 2,342
  • 2
  • 25
  • 33
  • 1
    You want 21 subfolders in folder 1, and 22 folders in folder 2? – Daniel Beck Jan 19 '12 at 20:04
  • Have you reviewed unix.SE? There's a good thread on this here: http://unix.stackexchange.com/questions/12976/how-to-move-100-files-from-a-folder-containing-thousands – chrisjlee Jan 19 '12 at 20:32
  • @DanielBeck no, I want the files to move to each folder. There are a different number of files going to each folder. – Rob Jan 19 '12 at 20:41
  • @ChrisJ.Lee That's pretty similar to what I was doing/have done before, I like it. Since the files match other files in another folder, I could `ls -l | grep ^- | wc -l` to get the numbers of lines. – Rob Jan 19 '12 at 20:45
  • 1
    @Rob Right. Still, different number of files into each directory. Automating that (including rules) is more effort than doing it yourself a few times. – Daniel Beck Jan 19 '12 at 20:50
  • It's easier to do 21, then 12, then 24, then 14, than it is to do that many individually. – Rob Jan 20 '12 at 01:54

3 Answers3

30

Since you said it's not always exactly 21 files than you need to move the files manually, and to do that effectively you could use brace expansion:

mv filename{001..21} dir1
mv filename{022..53} dir2
...
drrlvn
  • 6,155
  • 2
  • 21
  • 11
  • This looks like it could work, I'll try it out. – Rob Jan 20 '12 at 01:54
  • 1
    This works perfectly, if you add a wildcard after the brackets. This is exactly what I needed. – Rob Jan 20 '12 at 01:58
  • 2
    If the number is in the middle of the name, you can write `file{001..21}name`, you don't have to use wildcard. Anyway, happy it worked for you. – drrlvn Jan 20 '12 at 14:47
1

This will move the files as you described (except that the second range would be 022 to 042 for the second 21 files).

for ((i = 1; i <= 291; i++))
do
    ((d = (i - 1) / 21 + 1))
    printf -v file 'filename%03d' "$i"
    printf -v dir  'dirname%02d'  "$d"
    [[ -d "$d" ]] && mkdir "$d"
    mv "$f" "$d"
done
Dennis Williamson
  • 106,229
  • 19
  • 167
  • 187
1

What I mean is to move a lot of files(like ten thousands or a million), shell will complain about the file list too long if you just use {1..20}, so

In zsh, you can load the mv builtin:

setopt extended_glob zmodload

zsh/files

after doing that, you can use command like:

mv ./somefolder/{1..100000}.txt  pathto/yourfolder/

or if you are writing some shell scripts, you can do something like this:

for i in `seq $start $end`;  
    do  mv "prefix${i}suffix.txt" pathto/yourfolder/  
done

if you are not using zsh, you may refer to https://unix.stackexchange.com/questions/128559/solving-mv-argument-list-too-long

Arron Cao
  • 111
  • 3
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. Which answer are you referencing as the "more detailed answer"? – Ramhound Jul 20 '15 at 18:59
  • This doesn't really answer the question as OP wants to move different files to different directories. – DavidPostill Jul 20 '15 at 19:09