我有一个目录,其中包含一堆名称类似于 的文件a04x.txt
,每个文件都有一个相应的b04y.txt
文件。我需要能够对每对文件运行一些命令,并c04z.txt
为每对文件生成一个附加文件。
文件中的实际数字相当大且非常稀疏,因此简单地迭代从 1 到 99 的所有数字或类似的数字是行不通的。
目前我使用以下方法来处理该任务,但似乎是一个足够常见的任务,应该有一种更短/更好的方法来完成它:
for num in ./a*x.txt
do
num="${num##*/a}"
num="${num%x.txt}"
my_command a${num}x.txt b${num}y.txt c${num}z.txt
done
a${num}x.txt
理想情况下,当存在或b${num}y.txt
文件不具有相同编号的匹配文件时,我还希望收到警告。我还想要一种简单的方法,能够将文件集通过管道传输到,xargs
或者parallel
这样我就可以让它同时处理多组文件。
有一个更好的方法吗?
答案1
GNU 并行有一种方法可以做到这一点,并且作为奖励并行运行命令:
$ parallel my_command {} \
{= s/a([0-9]+)x.txt/b\1y.txt/ =} \
{= s/a([0-9]+)x.txt/c\1z.txt/ =} \
::: a*x.txt
这些替换是 Perl 代码。换行只是为了便于阅读——这是一行行。
答案2
一种方法是做
for afile in a*x.txt do bfile=${afile/a/b}; bfile=${bfile/x.txt/y.txt} cfile=${afile/a/c}; cfile=${cfile/x.txt/z.txt} my_command "$afile" "$bfile" "$cfile" done
尽管我认为这并不是一个很大的改进,并且在像
afoox.txtbarx.txt
.另请注意,这是 bash 特有的功能;它可能无法在其他符合 POSIX 标准的 shell 中工作(与 POSIX 指定的##
和不同)。%
这件事说起来很简单
if [ -f "$bfile" ] then my_command "$afile" "$bfile" "$cfile" else echo Error fi
捕获
a
文件异常值(例如,a17x.txt
没有相应的b17y.txt
)。如果你把
for afile # with no list, defaults to "$@"; i.e., the script’s arguments do bfile=${afile/a/b}; bfile=${bfile/x.txt/y.txt} cfile=${afile/a/c}; cfile=${cfile/x.txt/z.txt} if [ -f "$bfile" ] then my_command "$afile" "$bfile" "$cfile" else echo Error fi done
到脚本中,然后您可以使用文件名列表作为参数运行该脚本,它将处理它们。然后您可以通过或运行该脚本。
anumx.txt
xargs
parallel
作为上述过程的一部分检查
b
文件异常值(例如,b42y.txt
没有相应的a42x.txt
)并不简单,但很容易执行单独的循环:for bfile in b*y.txt do afile=${bfile/b/a}; afile=${afile/y.txt/x.txt} if [ ! -f "$afile" ] then echo Error fi done