我想以递归方式重命名路径下所有匹配的目录和文件,其前缀依赖于当前目录。
.
├── 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.1
、bin.1/ab.txt
、bin.1/cd.txt
、bin.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 mv
和help set
...