Bash脚本编程:并行for循环

3

我正在编写一个bash脚本,循环遍历两个完全相同的目录树,对匹配的文件运行diffs。我只需要知道设置两个并行运行的循环的正确语法。我还想递归地遍历目录,如果有额外的步骤来完成这一点,你能否提一下?

#!/bin/bash
FILES1=/path/to/one
FILES2=/path/to/two
for f1 in $FILES1; f2 in $FILES2
do
  echo "Processing $f1 $f2 file..."
done

2
你是否需要对$FILES1中的第一个文件与$FILES2中的第一个文件进行处理,然后是第二个文件与第二个文件,以此类推,还是要将$FILES1中的每个文件都与$FILES2中的每个文件进行处理(即叉积)? - Paŭlo Ebermann
4
“diff -Naur /path/to/one /path/to/two”有什么问题? - jamessan
保罗,我想要前者:第一个与第一个,第二个与第二个,以此类推。 - ted.strauss
@ted,你确定它们总是以相同的方式排序吗? - Paŭlo Ebermann
@paulo 不,我不能确定它们会以相同的顺序排序。 - ted.strauss
显示剩余2条评论
3个回答

3

不能保证两个目录中的文件顺序相同。

可以按照以下方式进行操作:

FILES1=/path/to/one
FILES2=/path/to/two
for f1 in $FILES1/*
do
  f2=$FILES2/`basename f1`
  # ...
done

如果您需要递归执行该操作:

cd $FILES1
for f1 in `find`; do
  f2=$FILES2/$f1
  # ...
done

3

diff已经内置了递归运行目录的功能。你可以运行 diff -Naur /path/to/one /path/to/two

  • -N 会显示新文件的差异,而不仅仅是指出它存在于第二个路径中
  • -a 将所有文件都视为文本,因此您可能需要或者不需要这个选项。
  • -u 使用常见的统一差异格式
  • -r 是重要的递归标志,在这种情况下要使用它

0

最接近的方法是嵌套for循环,即:

   for f in $FILES1 ; do
      for f2 in $FILES2 ; do
         if [ ${f##*/} = ${f2##*/} ]; then
             diff $f $f2
             break
         fi
      done
  done

若要遍历递归目录,您可以依赖于find返回要处理的文件列表。

 PATH1=/path/to/one
 PATH2=/path/to/two

 for f in $(find $PATH1 -print ) ; do
    for f2 in $(find $PATH2 -print ) ; do
       if [ ${f##*/} = ${f2##*/} ]; then
           diff $f $f2
           break
       fi
    done
done

抱歉,我现在没有测试这个的方法,${f##*/}可能不完全正确。意图是创建文件的基本名称(我猜你也可以使用$(basename $f),但每个文件需要2个进程的代价)。

这两个都是非常昂贵的过程,检查大量不匹配的文件名对。循环2内的break有所帮助。

另一种解决方案是依赖一个路径来创建驱动程序列表,然后使用提供的名称生成替代相对路径,即

for f in $FILES1 ; do
   f2=../two/$f{##*/}
   if [ -f ${f2} ] ; the
       diff $f $f2
   else
       printf "no alternate file found in ../two for f=${f}"
   fi
done

如果需要的话,您可以复制该循环并反转f2和f的位置,以检查系统的“另一侧”。

希望这可以帮助到您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接