Home > OS >  Using bash script to move folders based on their name
Using bash script to move folders based on their name

Time:11-16

I have a file (list.txt) with a list of directories in it, I want to read each line & then move the folders to a specific destination folder based on a number range in the directories name. It needs to work no matter how many directories are listed in the file because this will change daily.

In list.txt each line lists the directories like so;

/20211601_113212_hello_LGD_text.csv/KLS_8938I1_02020721_1/

I'm interested in the text in bold only, if that number is in a certain range e.g. 1-500 I want to move it to 'folder1', or 500-100 'folder2' and so on. The number will always precede the _1/ & will always be 4 numbers.

Using

grep -0 '......$' /list.txt | cut -d_ -f1

I've managed to grep the number I want, but I haven't been able to do anything with that information. I'm thinking I could split out each line into separate files & then use a for loop to iterate through each file, but I don't know how that would exactly work. Any suggestions?

CodePudding user response:

declare -i number
while IFS= read -r directory; do
  ((number = 10#"${directory: -7:-3}"))
  echo mv "${directory%/}" "folder$(((number   499) / 500))/"
done < list.txt
  • The syntax highlighting above malfunctions, # is not a start of a comment in this case.
  • The for-cycle reads whole lines without messing with spaces and without considering backslash escapes. This is to make sure that the directory names can be (almost) arbitrary.
  • We extract the number by starting at the 7. character from the end and ending before the 3. character from the end (both 1-based). Alternatively, the _1/ could be also stripped using ${directory%_1/}.
  • We treat the number as an integer (declare -i) and make sure it is not interpreted as an octal number (10#), because otherwise integer literals starting with 0 are octal (e.g. $((08)) yields an error).
  • We generate the mv command — remove the echo once satisfied with the output — where ${directory%/} strips the final slash (which you may want to tweak) and then $(((number 499) / 500)) generates the required 1-based “folder” number, so e.g. 499 yields 1, 500 yields (still) 1, 501 yields 2 etc. You will need to tweak that to your liking.
  • Related