Batch cycle and move files, please help

Hi guys, I'm not a great programmer but I do this project with a cool data and it has tons and tons of files which I need to sort before I can work with it.

The problem I need to solve is to move all files that look like

/X/Y/A_BC.xml

to

/X/B/A/Y/BC.xml

So it involves cycling through directories, reading filenames and creating new directories out of filenames. If you give me the solution for this exercise I'll do the rest myself of course.

I tried high-level languages, it takes too long. I need some kind of shell script for that.

Thanks!

Hi, where does the directory name "B" come from? Is that somehow derived from the original file name, or is it always B.

Also: what OS and shell are you using?

so I run this on my mac or on a remote server with some unix system (I'm using university resources), don't remember which one exactly

I need to read part of the filename and make a respective directory and put the file in there. I can identify part1 from the filename, because it has to be first 6 digits, the rest is part2_part3.

/dir1/dir2/part1part2_part3.xml

to

/dir1/part1/dir2/part2_part3.xml

roughly.

here's an example:

/levelone/level2/123456789_1.xml

to

/levelone/123456/level2/789_1.xml

I need to do that for all files in a given directory

The case in post #3:

/dir1/dir2/part1part2_part3.xml

to

/dir1/part1/dir2/part2_part3.xml

differs from the one in post #1:

/dir1/dir2/part1_part2part3.xml

to

/dir1/part2/part1/dir2/part2part3.xml

which one is it?

First one

So then part2 consists of 6 digits? Could you create an example?

Sorry for the confusion. The exact ordering does not really matter. This example would be enough I think:

move blablabla/folder/123456123_456.xml

to blablabla/123456/folder/123_456.xml

The exact ordering does matter for the solution at hand. Alright, let's take the 2nd one then after all..

Try:

for path in /dir1/dir2/*.xml
do
  [ -f "$path" ] || break
  basepath=${path%/*/*}
  lastpath=${path#"$basepath"/}
  lastdir=${lastpath%/*}
  file=${lastpath##*/}
  part23=${file#[0-9][0-9][0-9][0-9][0-9][0-9]}
  part1=${file%"$part23"}
  echo mkdir -p "${basepath}/${part1}/${lastdir}" 2>/dev/null
  echo mv "${path}" "${basepath}/${part1}/${lastdir}/${part23}"
done

Or if the top level directory is really only one level, like in your sample, you could try this alternative:

for path in /dir1/dir2/*.xml
do
  [ -f "$path" ] || break
  IFS=/ read basedir lastdir file << EOF
$path
EOF
  part23=${file#[0-9][0-9][0-9][0-9][0-9][0-9]}
  part1=${file%"$part23"}
  echo mkdir -p "${basedir}/${part1}/${lastdir}" 2>/dev/null
  echo mv "${path}" "${basedir}/${part1}/${lastdir}/${part23}"
done

Remove the echo statements when results are OK.

--
I'll leave it up to the reader to handle the case in post #1...