3

I have files with filenames such as:

text_2_2022-11-22_K03_10k_66_P578_B06_2999dl_text_693_coff_442.jpg text_2_2022-11-22_K03_10k_66_P578_B06_2999dl_text_693_coff_432.jpg text_2_2022-11-22_K05_10k_66_P578_B06_2999dl_text_693_coff_175.jpg text_2_2022-11-22_K05_10k_66_P578_B06_2999dl_text_693_coff_832.jpg text_2_2022-11-22_K08_10k_66_P578_B06_2999dl_text_693_coff_322.jpg text_2_2022-11-22_K08_10k_66_P578_B06_2999dl_text_693_coff_975.jpg

I want to create subfolders like:

K03_10k_66_P578_B06
K05_10k_66_P578_B06
K08_10k_66_P578_B06

and then move the files to the correct subfolder.

Other answers use parameter expansion but I could not figure out to do this given the more complex names. Therefore I wrote a grep/regex command that matches the needed part of the filename but could not implement it in a loop:

grep '[A-Z][0-9]*_[0-9]*[a-z]_[0-9]*_[A-Z][0-9]*_[A-Z][0-9]*'

I have found similar answers (1 2 3 4) to my question but my filenames are more complex than in those questions.

5
  • If the filenames are so complex that there's no consistent pattern to reference then this isn't possible. grep isn't for operating via the names of files. It's for printing data from the contents of files based on regular expressions. Commented Oct 9, 2022 at 0:09
  • The filenames are complex but consistent, especially the bold part I mentioned. I want to create groups/folders based on the different bold parts: K03..., K04... etc.
    – Nick_Z0
    Commented Oct 9, 2022 at 0:15
  • 3
    Then you'll need to provide more filenames so that there's a better idea of what's going on. Commented Oct 9, 2022 at 0:39
  • Do these filenames all consistently have 13 fields, each separated by an underscore character, before the .jpg suffix? And you want to use the 4th through the 8th field to construct a subfolder name, create that subfolder, and move the file into that subfolder?
    – Sotto Voce
    Commented Oct 9, 2022 at 9:29
  • I have edited the question to be clearer. @SottoVoce yes that is correct. The fields are consistent.
    – Nick_Z0
    Commented Oct 9, 2022 at 9:33

1 Answer 1

2

This worked for me in bash using parameter expansion, splitting filename into parts, re-joining a slice of the parts into the subfolder name:

# get list of .jpg files to work on
shopt -s nullglob
file_list=( *.jpg )

# quick exit if there are no files
[[ ${#file_list[@]} -lt 1 ]] && {
  echo 'No *.jpg files found' >&2
  exit 1
}

# handle each file in the list
for orig_fname in "${file_list[@]}"
do
  # get filename without .xyz suffix
  fname="${orig_fname%.*}"

  # split file name into parts on underscores
  IFS=_ fname_parts=( $fname )

  # join parts 3,4,5,6,7 into the subfolder name
  # note: includes trailing _ in name
  printf -v subfolder '%s_' "${fname_parts[@]:3:5}"
  subfolder="${subfolder%_}"  # strip trailing _ from name

  # create subfolder if needed
  mkdir -v -p "$subfolder"

  # move file to its subfolder
  mv -v "$orig_fname" "$subfolder"
done

Remove the -v from the mkdir and mv commands if you don't want their info to scroll on your screen.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .