![访问具有目录名公共部分的目录内文件的最佳方法](https://linux22.com/image/15494/%E8%AE%BF%E9%97%AE%E5%85%B7%E6%9C%89%E7%9B%AE%E5%BD%95%E5%90%8D%E5%85%AC%E5%85%B1%E9%83%A8%E5%88%86%E7%9A%84%E7%9B%AE%E5%BD%95%E5%86%85%E6%96%87%E4%BB%B6%E7%9A%84%E6%9C%80%E4%BD%B3%E6%96%B9%E6%B3%95.png)
标题根本不言自明,但我不知道如何正确地表达它。我将用一个例子来解释。
我有一个这样的目录结构:
结果/
test_0_part1_x000/ test_0_part2_x010/ test_0_part3_x122/ test_1_part1_x121/ test_1_part2_x009/ ....
等等。基本上有一个 result/ 目录,其中有大约 500 个目录。这些目录按测试“分组”,因此所有 test_0_part* 目录都引用相同的测试平台(假设有大约 50 个测试,所以我有 test_0_* 到 test_49_* 目录)。
在每个目录中,我需要收集一个文件并将其分组到一个目录中,如果是 test_0,则为 test_0/,并且必须包含 test_0_part* 目录中的所有文件。
实际上,我的方法是迭代 result/ 中的所有目录,并通过比较目录名称,将文件收集到正确的最终目录中。它正在工作,但似乎一点也不聪明,因为我可以使用正则表达式或类似的东西来处理问题。不幸的是,我的 bash 脚本以及一般来说我对 bash 的理解仍然非常基础,我不知道应该看什么来改进代码。我想利用正则表达式来执行更干净的文件选择和复制,这比仅按顺序迭代所有文件更安全。
我的代码如下所示:
#! /bin/bash
OUTDIR="" #output dir - where to place the files from same test
INFILES="" #collection of input files for each test
last_dir=""
#iterate through all the directories in result/
for d in */; do
subdirname=${d%???????????} #getting only the first part of dir name (i.e. test0, test1, etc)
#if new directory is different from the last one, then it is related to a new test. move alle the files collected so far to the OUTDIR directory and clean the OUTDIR content
if [[ "$last_dir" != "$subdirname" && ! -z "$last_dir" ]]; then
echo "copying for $last_dir test:"
echo "$INFILES" | tr " " "\n"
echo "output directory: $OUTDIR"
mkdir ${OUTDIR}
mv ${INFILES} ${OUTDIR}/
OUTDIR=""
fi
#if output dir is empty, then get the name from the current dir and clean the input files list
if [ -z "$OUTDIR" ]; then
OUTDIR=${subdirname}
INFILES=""
fi
# collect file(s) in the current directory and append to the list
for fname in ${d}*;
do
INFILES="${INFILES} ${fname}"
done
last_dir=${subdirname}
done
任何帮助表示赞赏!
答案1
使用zsh
, 将所有文件移至:test_n_part*/*
test_n
autoload zmv
mkmv() {mkdir -p -- $2:h && mv -- "$@"}
zmv -n -P mkmv '(test_<->)_part*/(*)' '$1/$2'
(-n
如果愿意,请删除以进行空运行)。
添加(#qD)
到源模式还可以移动隐藏文件。