user2300940
user2300940

Reputation: 2385

Rename files in multiple subfolders

I have multiple unique directories that each contain a file named filtered_feature_bc_matrix.h5. I want to paste the directory-name onto the filename to make the filename unique within each folder. Is this possible?

./sample_scRNA_unsorted_98433_Primary_bam/outs/filtered_feature_bc_matrix.h5
./sample_scRNA_unsorted_77570_Primary_bam/outs/filtered_feature_bc_matrix.h5

out:

./sample_scRNA_unsorted_98433_Primary_bam/outs/sample_scRNA_unsorted_98433_Primary_bam_filtered_feature_bc_matrix.h5
./sample_scRNA_unsorted_77570_Primary_bam/outs/sample_scRNA_unsorted_77570_Primary_bam_filtered_feature_bc_matrix.h5

Upvotes: 1

Views: 126

Answers (2)

Renaud Pacalet
Renaud Pacalet

Reputation: 28965

For completeness here is a solution with only bash built-in:

shopt -s globstar nullglob
name="filtered_feature_bc_matrix.h5"
for f in */**/"$name"; do mv "$f" "${f%/*}/${f%%/*}_$name"; done

Upvotes: 5

Cyrille Pontvieux
Cyrille Pontvieux

Reputation: 2461

find . -type f -name 'filtered_feature_bc_matrix.h5' \
-exec sh -c \
'fp="$1"; d=$(echo "$fp"|cut -d/ -f2); echo $(dirname "$fp")/${d}_$(basename "$fp")' \
-- '{}' \;
  • find allows to iterate the files with relative path
  • -exec allows to do action on '{}' which is the file path
  • sh is used to simplify the action
  • dirname and basename allows to extract directories or filename.
  • cut is used to extract only the first directory (second field as the first one is .)

To rename:

find . -type f -name 'filtered_feature_bc_matrix.h5' \
-exec sh -c \
'fp="$1"; d=$(echo "$fp"|cut -d/ -f2); mv -v "$fp" "$(dirname "$fp")/${d}_$(basename "$fp")"' \
-- '{}' \;

Upvotes: 2

Related Questions