文件夹比较

文件夹比较

我有两个文件夹具有相似的子文件夹结构,我想进行比较。例如:

A 
├── child-1
├── child-2
├── child-3
├── child-4
├── child-5

B 
├── child-1-some-text
├── child-2-more-text
├── child-3-nothing
├── child-6-random-text
├── child-7-more-random-text

我想列出所有以A为子文件夹前缀的子文件夹,B并列出相应的子文件夹B。预期输出为

child-1 -- child-1-some-text
child-2 -- child-2-more-text
child-3 -- child-3-nothing

次要要求:如果有多个匹配项B,则应该给出错误/警告。

我的解决方案

cd A
for f in `ls -d */`; 
do
    cd B;
    new_dirs=(`ls -1d $f*`);
    cd -;
    if [ ${#new_dirs[@]} -eq 0 ]
    then
        ## DO_Nothing
        continue;
    elif  [ ${#new_dirs[@]} -gt 1 ]
    then
        echo "Multiple matches to $f";
        continue;
    else
        echo "Unique Match found to $f -- ${new_dirs[0]}";
        continue;
    fi;    
done

问题:

$f对于那些在中没有对应子文件夹的值B,数组构造会给出错误。例如:

ls:无法访问“child-4*”:没有该文件或目录

问题

  • 如何摆脱这些错误?
  • 有没有更好的实现目标的方法然后是我的代码中的方法?

提前致谢!

答案1

更好的方法

不要解析ls; 改用 globs。实际上您已经在使用 globs,只是将它们包装在 中ls,这是没有意义的。您只需要nullglob在没有匹配项时打开即可。

避免也cd会使事情简单化。

#!/bin/bash

shopt -s nullglob

dir1=A
dir2=B

for dir in "$dir1"/*/; do
    basename="$(basename -- "$dir")"
    dirs_match=( "$dir2/$basename"*/ )
    case ${#dirs_match[@]} in
    0)
        ;;
    1)
        echo "Unique match for $dir: ${dirs_match[*]}"
        ;;
    *)
        echo "Multiple matches for $dir: ${dirs_match[*]}" >&2
        ;;
    esac
done

输出:

Unique match for A/child-1/: B/child-1-some-text/
Unique match for A/child-2/: B/child-2-more-text/
Multiple matches for A/child-3/: B/child-3-nothing/ B/child-3-something/

我添加了B/child-3-something测试次要要求。这将创建用于测试的目录结构:

mkdir -p A/child-{1..5} B/child-{1-some-text,2-more-text,3-nothing,3-something,6-random-text,7-more-random-text}

顺便一提,壳牌检测对于查找 shell 脚本中的问题非常有用。

答案2

调用ls不存在的文件夹会抛出您遇到的错误消息。简单的方法是将脚本中的第 5 行替换为以下内容来忽略此错误:new_dirs=(`ls -1d $f* 2> /dev/null`);

相关内容