The question is published on by Tutorial Guruji team.
I have some files whose name looks like this:
XXXXX_S1_X_XX_X.txt XXXXX_S2_X_XX_X.txt XXXXX_S3_X_XX_XXX.txt S4_X_XX_X.txt XXXXX_S5_XX_X.txt ...
I created a list of folders named: S1
, S2
, S3
, …. I would like to move the file XXXXX_S1_X_XX_X.txt
in the folder S1
, the file XXXXX_S2_X_XX_X.txt
in the folder S2
and so on. I wrote this simple loop but I don’t know how to copy/move files according to the pattern matching S* in the corresponding folder:
for i in My_list_of_folders.txt do dir=${i%.txt} mkdir "$dir" cp "$i" "$dir" done
Answer
A slightly modified loop:
for pattern in S1 S2 S3 S4; do mkdir -p ./"$pattern" for filename in ./*"$pattern"*; do [ ! -f "$filename" ] && continue mv -i "$filename" "$pattern"/ done done
This loops through the pattern strings S1
, S2
, S3
and S4
. The inner loop uses the current pattern string to look for names in the current directory that contains the string anywhere in it. It skips non-regular files (like the directories S1
, S2
etc. themselves) and moves everything else that matches to the appropriate directory for that pattern string.
As slm points out in comments (now deleted), the operations in the inner loop may in this case well be shortened into just
[ ! -f "$filename" ] || mv -i "$filename" "$pattern"/
or
[ -f "$filename" ] && mv -i "$filename" "$pattern"/
If you have overlapping patterns, such as S1
and S11
, then you will need to do the longer patterns first.