我有以下目录结构:
├── 15_10_29
│ ├── NAME
│ ├── NAME_2
│ ├── NAME_3
│ ├── NAME_4
│ └── NAME_5
├── 15_11_09
│ ├── NAME
│ ├── NAME_2
│ ├── NAME_3
│ └── NAME_4
└── 15_11_17
├── NAME
├── NAME_2
├── NAME_3
└── NAME_4
在每个NAME子目录中都有一个名为atom.pdb的文件。我想返回一个具有相同“NAME”目录名的atom.pdb文件列表。
./15_10_29/NAME/atom.pdb
./15_11_09/NAME/atom.pdb
./15_11_17/NAME/atom.pdb
./15_10_29/NAME_2/atom.pdb
./15_11_09/NAME_2/atom.pdb
./15_11_17/NAME_2/atom.pdb
......依此类推。
我似乎无法概念化如何做到这一点。我想我会想使用find但是我对bash globbing更好,在这种情况下代码必须很长,所以我确信有一个更优雅的解决方案。
修改:
find . -wholename '*atom.pdb' | sort -t / -k3,3
正在返回所需的结果:
./15_10_29/NAME/atom.pdb
./15_11_09/NAME/atom.pdb
./15_11_17/NAME/atom.pdb
./15_10_29/NAME_2/atom.pdb
./15_11_09/NAME_2/atom.pdb
./15_11_17/NAME_2/atom.pdb
./15_10_29/NAME_3/atom.pdb
./15_11_09/NAME_3/atom.pdb
./15_11_17/NAME_3/atom.pdb
./15_10_29/NAME_4/atom.pdb
./15_11_09/NAME_4/atom.pdb
./15_11_17/NAME_4/atom.pdb
./15_10_29/NAME_5/atom.pdb
但是现在我不确定如何解析这些并通过“NAME”将它们分解为存储在数组或连接的字符串变量中。
编辑2: 以下是我提出的建议:
ARR=()
for i in /*/*/ ; do
ARR+=($(basename ${i}))
done
while read i; do
ARR2=(/*/${i}/atom.pdb)
echo ${ARR2[@]}
done < <(echo ${ARR[@]} | tr " " "\n" | sort -u)
答案 0 :(得分:1)
您可以在Bash 4中执行此操作:
shopt -s globstar nullglob
# to find all files named atom.pdb
echo **/atom.pdb
# to find all atom.pdb files under a parent dir 'NAME'
echo **/NAME/atom.pdb
# to print all atom.pdb files, grouped by the same parent
while read -r dir; do
files=$(echo **/"$dir"/atom.pdb)
echo "Processing files $files"
# do the processing
done < <(ls **/atom.pdb | cut -f2 -d/ | sort -u) # ls makes sure each file is on a different line, unless echo
给出这个输出:
Processing files 15_10_29/NAME/atom.pdb 15_11_09/NAME/atom.pdb 15_11_17/NAME/atom.pdb
Processing files 15_10_29/NAME_2/atom.pdb 15_11_09/NAME_2/atom.pdb 15_11_17/NAME_2/atom.pdb
答案 1 :(得分:1)
看起来像后期处理这种排序是一个很好的方法:
find . -wholename '*NAME*atom.pdb' | sort -t / -k3,3
如果你需要分组:
find . -name 'atom.pdb' | sort -t / -k3,3 |
awk -F/ '$3 != last{print ""}{last=$3}1'
答案 2 :(得分:0)
嗯,我毕竟以bash shell的方式成功解决了这个问题。
ARR=()
for i in /*/*/ ; do
ARR+=($(basename ${i}))
done
while read i; do
ARR2=(/*/${i}/atom.pdb)
echo ${ARR2[@]}
done < <(echo ${ARR[@]} | tr " " "\n" | sort -u)
ARR包含一系列唯一的NAME值,ARR2包含在其父目录中具有相同NAME值的匹配文件名的全局列表。
如果有更优雅的方式来解决这个问题,请随时纠正我。它似乎有效。