通常:)我有两组具有相同名称但扩展名不同的输入文件。
使用bash我创建了一个简单的脚本,它创建了2个具有相同元素名称的列表,同时从2个目录中循环了2组文件,并且只使用名称没有扩展名作为这些列表的元素:
#!/bin/bash
workdir=/data2/Gleb/TEST/claire+7d4+md/water_analysis/MD1
traj_all=${workdir}/tr_all
top_all=${workdir}/top_all
#make 2 lists for both file types
Trajectories=('');
Topologies=('');
#looping of 1st input files
echo "Trr has been found in ${traj_all}:"
for tr in ${traj_all}/*; do # ????
tr_n_full=$(basename "${tr}")
tr_n="${tr_n_full%.*}"
Trajectories=("${Trajectories[@]}" "${tr_n}");
done
#sort elements within ${Trajectories[@]} lists!! >> HERE I NEED HELP!
#looping of 2nd files
echo "Top has been found in ${top_all}:"
for top in ${top_all}/*; do # ????
top_n_full=$(basename "${top}")
top_n="${top_n_full%.*}"
Topologies=("${Topologies[@]}" "${top_n}");
done
#sort elements within ${Topologies[@] lists!! >> HERE I NEED HELP!
#make input.in file for some program- matching of elements from both lists >> HERE I NEED HELP!
for i in $(seq 1 ${#Topologies[@]}); do
printf "parm $top_all/${Topologies[i]}.top \ntrajin $traj_all/${Trajectories[i]}.mdcrd\nwatershell ${Area} ${output}/watershell_${Topologies[i]}_${Area}.dat > output.in
done
如果有人为我提供了改进此脚本的可能性,我会感激不尽: 1)我需要在每个列表中添加最后一个元素后,以相似的模式对两个列表中的元素进行排序; 2)我需要在脚本的最后一步添加一些测试,它将创建最终的output.in文件,以防两个列表中的元素相同(原则上在这种情况下它总是应该是相同的!)在此操作期间由printf匹配。
感谢您的帮助,
格列勃
答案 0 :(得分:0)
这是创建数组的一种更简单的方法:
# Create an empty array
Trajectories=();
for tr in "${traj_all}"/*; do
# Remove the string of directories
tr_base=${tr##*/}
# Append the name without extension to the array
Trajectories+="${tr_base%.*}"
done
在bash中,这通常会产生一个排序列表,因为glob中*
的扩展是有序的。但您可以使用sort
对其进行排序;如果您确定文件名中没有换行符,则最简单:
mapfile -t sorted_traj < <(printf %s\\n "${Trajectories[@]}" | sort)
要比较两个已排序的数组,您可以使用join
:
# convenience function; could have helped above, too.
lines() { printf %s\\n "$@"; }
# Some examples:
# 1. compare a with b and print the lines which are only in a
join -v 1 -t '' <(lines "${a[@]}") <(lines "${b[@]}")
# 2. create c as an array with the lines which are only in b
mapfile -t c < <( join -v 2 -t '' <(lines "${a[@]}") <(lines "${b[@]}") )
如果您创建两个差异列表,那么如果两个列表都为空,则两个数组相等。但是,如果你期望两个数组都是相同的,如果这是时间关键的(可能不是),你可以做一个简单的预检:
if [[ "${a[*]}" = "${b[*]}" ]]; then
# the arrays are the same
else
# the arrays differ; do some more work to see how.
fi