Home > Mobile >  bash script to create directories named after file names then move and rename files to corresponding
bash script to create directories named after file names then move and rename files to corresponding

Time:05-26

I looked all day from tutorials to ready made bash scripts, but couldn't find what I need. Also I never wrote a bash script before... :/

Here's my problem (to quote from full metal jacket: "there are many like it, but this one is mine"): I have a directory with 120 files that come in triplets (in bold I marked what's unique to every file triplet): GSM6025613_SJWLM030043_D1_barcodes.tsv
GSM6025613_SJWLM030043_D1_features.tsv
GSM6025613_SJWLM030043_D1_matrix.mtx

GSM6025615_SJWLM071563_D1_barcodes.tsv
GSM6025615_SJWLM071563_D1_features.tsv
GSM6025615_SJWLM071563_D1_matrix.mtx

...

I would like to have a bash script that creates new directories with names according to the triplets unique strings (f.e. '613', '615') moves the three corresponding files (*barcode.tsv, *features.tsv, *matrix.mtx) to the corresponding directory and renames them so that the files are just called "barcode.tsv", "features.tsv" and "matrix.mtx".

I tried it with a for loop, but I'm pretty blank on bash scripting and beyond the second line, honestly, it's all jibberish to me (for now)... :/

#!/bin/bash for f in *.{tsv,mtx} do ... done

I appreciate any help!

CodePudding user response:

You can use sed to split the file name into its components, something like this

file='GSM6025615_SJWLM071563_D1_barcodes.tsv'
eval $(sed -E 's/(GSM....)([0-9] )_(.*)_(.*)_(.*)\.tsv/n=\2;f=\5;/' <<< "$file")
echo $n
615
echo $f
barcodes

eval allows you to take the output of sed (the n and f variable assignments) and convert it to variables.

CodePudding user response:

Try this Shellcheck-clean code (maybe on a copy of your directory first!):

#! /bin/bash -p

shopt -s nullglob

for file in GSM6025[0-9][0-9][0-9]_*_{features.tsv,matrix.mtx,barcodes.tsv}
do 
    dir=${file#GSM6025}
    dir=${dir%%_*}

    newfile=${file##*_}

    mkdir -p -v -- "$dir"
    mv -n -v -- "$file" "$dir/$newfile"
done
  • Related