Home > Software engineering >  moving files to their respective folders using bash scripting
moving files to their respective folders using bash scripting

Time:05-30

I have files in this format:

2022-03-5344-REQUEST.jpg
2022-03-5344-IMAGE.jpg
2022-03-5344-00imgtest.jpg
2022-03-5344-anotherone.JPG
2022-03-5343-kdijffj.JPG
2022-03-5343-zslkjfs.jpg
2022-03-5343-myimage-2010.jpg
2022-03-5343-anotherone.png
2022-03-5342-ebee5654.jpeg
2022-03-5342-dec.jpg
2022-03-5341-att.jpg
2022-03-5341-timephoto_december.jpeg
....

about 13k images like these.

I want to create folders like:

2022-03-5344/
2022-03-5343/
2022-03-5342/
2022-03-5341/
....

I started manually moving them like:

mkdir name
mv name-* name/

But of course I'm not gonna repeat this process for 13k files.

So I want to do this using bash scripting, and since I am new to bash, and I am working on a production environment, I want to play it safe, but it doesn't give me my results. This is what I did so far:

#!/bin/bash

name = $1

mkdir "$name"

mv "${name}-*" $name/

and all I can do is: ./move.sh name for every folder, I didn't know how to automate this using loops.

CodePudding user response:

With bash and a regex. I assume that the files are all in the current directory.

for name in *; do
  if [[ "$name" =~ (^....-..-....)- ]]; then
    dir="${BASH_REMATCH[1]}";    # dir contains 2022-03-5344, e.g.
    echo mkdir -p "$dir" || exit 1;
    echo mv -v "$name" "$dir";
  fi;
done

If output looks okay, remove both echo.

CodePudding user response:

Try this

xargs -i sh -c 'mkdir -p {}; mv {}-* {}' < <(ls *-*-*-*|awk -F- -vOFS=- '{print $1,$2,$3}'|uniq)

Or:

find . -maxdepth 1 -type f -name "*-*-*-*" | \
awk -F- -vOFS=- '{print $1,$2,$3}' | \
sort -u | \
xargs -i sh -c 'mkdir -p {}; mv {}-* {}'

Or find with regex:

find . -maxdepth 1 -type f -regextype posix-extended -regex ".*/[0-9]{4}-[0-9]{2}-[0-9]{4}.*"

CodePudding user response:

You could use awk

$ cat awk.script
/^[[:digit:]-]/ && ! a[$1]   {
    dir=$1
} /^[[:digit:]-]/ {
    system("sudo mkdir " dir )
    system("sudo mv " $0" "dir"/"$0)
}

To call the script and use for your purposes;

$ awk -F"-([0-9] )?[[:alpha:]] .*" -f awk.script <(ls)

You will see some errors such as;

mkdir: cannot create directory ‘2022-03-5341’: File exists

after the initial dir has been created, you can safely ignore these as the dir now exist.

The content of each directory will now have the relevant files

$ ls 2022-03-5344
2022-03-5344-00imgtest.jpg  2022-03-5344-IMAGE.jpg  2022-03-5344-REQUEST.jpg  2022-03-5344-anotherone.JPG
  • Related