1

I have a directory full of files similar to these:

3260_661901_2008-2008.dat
3260_661901_2009-2009.dat
3260_661901_2010-2010.dat
3260_661901_2011-2011.dat
3260_661901_por-1998.dat
3260_662336_1999-1999.dat
3260_662336_2000-2000.dat
3260_662336_2001-2001.dat
3260_662336_2002-2002.dat

I would like to split off the files into directories names after the 6th and 7th character in the filename like this:

66/3260_661901_2008-2008.dat
66/3260_661901_2009-2009.dat
66/3260_661901_2010-2010.dat
66/3260_661901_2011-2011.dat
67/3260_671901_por-1998.dat
67/3260_672336_1999-1999.dat
67/3260_672336_2000-2000.dat
88/3260_882336_2001-2001.dat
88/3260_882336_2002-2002.dat

Is there a quick one liner command I can use to create the subdirectories and move the files into them?

I should mention the directory has over 33k files in it.

1

try

ls |  awk '{d=substr($0,6,2) ; printf "mkdir %s ; mv %s %s\n",d,$1,d }' | bash
  • in this case, you can use ls result as input.
  • you'll get error message as dir exists after first mkdir, to get rid use :

    awk '{d=substr($0,6,2) ; printf "test -d %s || mkdir %s ; mv %s %s\n",d,d,$1,d }'
    
  • 2
    use mkdir -p to avoid an error msg. – meuh Sep 9 '15 at 8:05
  • no way !! I like unnecessary complexity – Archemar Sep 9 '15 at 8:07
6

Assuming you are using bash you could run

for f in *.dat; do mkdir -p "${f:5:2}"; mv "$f" "${f:5:2}/"; done

or (if there are too many files for for f in *.dat to work)

while read f; do mkdir -p "${f:5:2}"; mv "$f" "${f:5:2}/"; done < ls

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.