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.

6
  • 1
    You want 21 subfolders in folder 1, and 22 folders in folder 2?
    – Daniel Beck
    Jan 19, 2012 at 20:04
  • Have you reviewed unix.SE? There's a good thread on this here: unix.stackexchange.com/questions/12976/…
    – chrisjlee
    Jan 19, 2012 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, 2012 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, 2012 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, 2012 at 20:50

3 Answers 3

29

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
...
3
  • This looks like it could work, I'll try it out.
    – Rob
    Jan 20, 2012 at 1:54
  • 1
    This works perfectly, if you add a wildcard after the brackets. This is exactly what I needed.
    – Rob
    Jan 20, 2012 at 1: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, 2012 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
0
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

2
  • 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, 2015 at 18:59
  • This doesn't really answer the question as OP wants to move different files to different directories.
    – DavidPostill
    Jul 20, 2015 at 19:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.