我有一个包含60k子目录的目录。
每个子目录都有两个(子)子目录(2_4
,cov_bound
)。我感兴趣的是子目录2_4
。所以它看起来像这样:
main_directory/foo/2_4/
每个子目录foo
包含一个.pdb
文件
每个2_4
子目录包含0个或更多.txt
个文件。
所以它看起来像这样:
main_directory/foo/1A2C.pdb
main_directory/foo/2_4/XLS#A#207.txt
main_directory/foo/2_4/XLS#B#209.txt
main_directory/foo/2_4/XLS#C#207.txt
main_directory/foo/2_4/SOS#D#145.txt
我正在尝试将文件名中的第一个#
之前的字母(本例中为XLS
,SOS
)加入到pdb文件的文件名中:
1A2C_XLS_SOS.pdb
多个文件以XLS#
开头,但每个前缀只能使用一次。
我遇到的第二个问题是,如果子目录2_4
为空,则输出为1A2C_.pdb
,我想摆脱它。因此,如果2_4
为空,则不要处理它。只需在具有2_4
个文件的.txt
子目录上运行它。
我试图用bash写一些内容,但这仅适用于.txt
中的一个2_4
文件,并且还考虑了空2_4
。
所有这些带有新文件名的pdb文件都应该复制到另一个目录中。
我在bash中试过这个:
mkdir pdb_files
for i in */ ; do cd $i ; pwd ; a=`head -n1 2_4/*txt | awk '{print $4}' ` ; j=`ls *pdb` ; cp $j ../pdb_files/${j//.pdb/_$a}.pdb ; cd ../ ; done
我是从main_directory
运行它。
答案 0 :(得分:1)
这里有一个裂缝:
TARGETDIR=./pdb_files
for dir in $(find . -maxdepth 1 -type d -not -name .)
do
PREFIXES=( $(
for file in ${dir}/2_4/*.txt
do
filename=$(basename $file)
echo ${filename%%\#*.txt}
done | sort -u
) )
if [ ${PREFIXES[0]} != '*.txt' ]
then
for oldpdb in ${dir}/*.pdb
do
pdbname=${oldpdb%%.pdb}
pdbsuffix=$(IFS=_ ; echo "${PREFIXES[*]}")
newpdb=${TARGET}/$(basename $pdbname)_${pdbsuffix}.pdb
echo -------------------------
echo Directory: $dir
echo Old file name: $oldpdb
echo New file name: $newpdb
# I think this is what you want?
cp $oldpdb $newpdb
done
else
for oldpdb in ${dir}/*.pdb
do
echo -------------------------
echo Directory: $dir
echo Old file name: $oldpdb
echo New file name: do not rename file
# maybe you want to copy unmodified files?
# cp $oldpdb $TARGET
done
fi
done
这是我的目录结构,来自main_directory:
main_directory/
├── foo
│ ├── 1A2C.pdb
│ └── 2_4
│ ├── SOS#D#145.txt
│ ├── XLS#A#207.txt
│ ├── XLS#B#209.txt
│ └── XLS#C#207.txt
├── foo2
│ ├── 1A2B.pdb
│ └── 2_4
└── run
并且' ./ run'的输出在main_directory中:
-------------------------
Directory: ./foo2
Old file name:
New file name: do not rename file
-------------------------
Directory: ./foo
Old file name: ./foo/1A2C.pdb
New file name: ./foo/1A2C_SOS_XLS.pdb
编辑:我错过了#34;将这些新文件复制到其他目录"有点,所以我稍微调整了一下脚本。
编辑2:对melpomene的称赞;很抱歉偷了你的问题,到我到这儿的时候你已经把它清理干净得足以让它变得有意义了。对不起:(
编辑3:嗯,目前还不是很清楚你想要对这些文件做些什么。困难的部分似乎打赌获得正确的新文件名,我认为这段代码就是这样。我已经改变它,所以它只打印出旧的和新的PDB文件名,从那里你可以插入你自己的逻辑来重命名或复制它们你认为合适吗?这个脚本不会cd
进入每个目录,它会从主目录中执行所有操作。请尝试使用您的数据子集,并告诉我它是如何进行的。
编辑4:更改了我们移动新文件的逻辑
编辑5:在这里提出一些有问题的代码。这里的代码没有全部调试/尝试来演示脚本的内部工作原理。这将完成您所追求的目标,而不是谈论它一直在做什么。
编辑6:我之前的代码对于只有一个.txt文件的目录不起作用。这适用于我所知道的所有用例。
#!/bin/bash
TARGETDIR=./pdb_files
for dir in $(find . -maxdepth 1 -type d -not -name .)
do
PREFIXES=( $(
for file in ${dir}/2_4/*.txt
do
filename=$(basename $file)
echo ${filename%%\#*.txt}
done | sort -u
) )
if [ ${#PREFIXES[@]} -ge 1 -a "${PREFIXES[0]}" != '*.txt' ]
then
for oldpdb in ${dir}/*.pdb
do
pdbname=${oldpdb%%.pdb}
pdbsuffix=$(IFS=_ ; echo "${PREFIXES[*]}")
newpdb=${TARGETDIR}/$(basename $pdbname)_${pdbsuffix}.pdb
cp $oldpdb $newpdb
done
fi
done
之前的树:
main_directory
├── foo
│ ├── 1A2C.pdb
│ └── 2_4
│ ├── SOS#D#145.txt
│ ├── XLS#A#207.txt
│ ├── XLS#B#209.txt
│ └── XLS#C#207.txt
├── foo2
│ ├── 1A2B.pdb
│ └── 2_4
├── foo3
│ ├── 2_4
│ │ └── XLS#C#100.csv
│ └── 2A3B.pdb
├── foo4
│ ├── 2_4
│ │ └── XLS#D#201.txt
│ └── 3A3B.pdb
├── pdb_files
└── run
后:
main_directory
├── foo
│ ├── 1A2C.pdb
│ └── 2_4
│ ├── SOS#D#145.txt
│ ├── XLS#A#207.txt
│ ├── XLS#B#209.txt
│ └── XLS#C#207.txt
├── foo2
│ ├── 1A2B.pdb
│ └── 2_4
├── foo3
│ ├── 2_4
│ │ └── XLS#C#100.csv
│ └── 2A3B.pdb
├── foo4
│ ├── 2_4
│ │ └── XLS#D#201.txt
│ └── 3A3B.pdb
├── pdb_files
│ ├── 1A2C_SOS_XLS.pdb
│ └── 3A3B_XLS.pdb
└── run