14

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.

  • 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: unix.stackexchange.com/questions/12976/… – 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
26

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
...
| improve this answer | |
  • This looks like it could work, I'll try it out. – Rob Jan 20 '12 at 1:54
  • 1
    This works perfectly, if you add a wildcard after the brackets. This is exactly what I needed. – Rob Jan 20 '12 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 '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
| improve this answer | |
  • It's not always 21 files, but thanks. – Rob Jan 19 '12 at 20:36
0

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

| improve this answer | |
  • 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

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.