查找并重命名每个 basedir 下的基本目录和文件,添加前缀

查找并重命名每个 basedir 下的基本目录和文件,添加前缀

我想以递归方式重命名路径下所有匹配的目录和文件,其前缀依赖于当前目录。

.
├── G1_BIN_REFINEMENT
│   └── marker_genes
│       └── identify
│           └── intermediate_results
│               └── marker_genes
│                   ├── bin.1
│                   │   ├── ab.txt
│                   │   └── cd.txt
│                   └── bin.2
│                       ├── ab.txt
│                       └── cd.txt
├── G2_BIN_REFINEMENT
│   └── marker_genes
│       └── identify
│           └── intermediate_results
│               └── marker_genes
│                   ├── bin.1
│                   │   ├── ab.txt
│                   │   └── cd.txt
│                   └── bin.2
│                       ├── ab.txt
│                       └── cd.txt  

目录下的G1_BIN_REFINEMENT前缀为G1_。要修改的文件和目录为bin.1bin.1/ab.txtbin.1/cd.txtbin.2...

预期结果是

in the dir G1_BIN_REFINEMENT
bin.1        ---> G1_bin.1 
bin.1/ab.txt ---> G1_bin.1/G1_ab.txt
...
in the dir G2_BIN_REFINEMENT
bin.1        ---> G2_bin.1 
bin.1/ab.txt ---> G2_bin.1/G2_ab.txt
...

但是,输出是添加到根目录的前缀,我得到了G1_G1_BIN_REFINEMENT/marker_genes/identify/intermediate_results/marker_genes/

这是我的语法,

for d in *_BIN_REFINEMENT/marker_genes/identify/intermediate_results/marker_genes/
do
#get sample name from path
sample=$(echo $d | cut -d/ -f1 | cut -d_ -f1)
echo $sample
  
#to recursively rename dir and files
find $d -exec env var=$sample rename -n 's/^/$ENV{var}_/' '{}' \+
done

答案1

首先我们在TesT目录中重新创建你的结构

mkdir TesT; cd TesT
mkdir -p G{1,2}_BIN_REFINEMENT/marker_genes/identify/intermediate_results/marker_genes/bin.{1,2}
touch G{1,2}_BIN_REFINEMENT/marker_genes/identify/intermediate_results/marker_genes/bin.{1,2}/{ab.txt,cd.txt}

的输出tree将确认

├── G1_BIN_REFINEMENT
│   └── marker_genes
│       └── identify
│           └── intermediate_results
│               └── marker_genes
│                   ├── bin.1
│                   │   ├── ab.txt
│                   │   └── cd.txt
│                   └── bin.2
│                       ├── ab.txt
│                       └── cd.txt

然后我们针对您的具体情况编写脚本

#!/bin/bash
set -e               # You will interrupt script on 1st error
OldDir=$(pwd)        # Here we save our current position   
for d in *_BIN_REFINEMENT/marker_genes/identify/intermediate_results/marker_genes/
do                   # below you get sample name from path
sample=$(echo $d | cut -d/ -f1 | cut -d_ -f1)
echo "# sample $sample"
# ------------------------------------------------------------ #
# find "$d"          # Commented out: from this output you may #
#                    # understand why your results.            #
# ------------------------------------------------------------ #
cd "$d"              # You enter in the current dir
  for d2 in bin* 
  do 
   cd "$d2"          # You enter in the current bin.xx subdir
    for fn in *.txt  # You cycle on each file
    do
       mv -i "$fn" "${sample}_$fn" # Only adding a prefix on file
    done
   cd -              # You come back to the previous dir
   mv -i "$d2" "${sample}_$d2"     # Only adding a prefix on dir
  done
cd "$OldDir"         # Here you come back where you take "d"
done
exit 0               # All good...

笔记

  • 因为你要移动文件,所以最好谨慎行事(set -e 并且mv -i交互性强)
  • 保持好奇心:更多信息man mvhelp set...

相关内容