bash 如何比较shell脚本中两个目录中的文件名?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28205735/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:50:50  来源:igfitidea点击:

How do I compare file names in two directories in shell script?

bashshell

提问by Apple

Right now, this is what my code looks like:

现在,这就是我的代码的样子:

#!/bin/bash

Dir1=
Dir2=

for file1 in $Dir1/*; do
    for file2 in $Dir2/*; do
        if [[ $file1 == $file2 ]]; then
            echo "$file1 is contained in both directories"
        fi
    done
done

I am trying to compare the file names of the two directories entered and say that the file is in both directories if the filename matches. When I try to run it though, nothing is echo-ed even though I have the same file in both directories.

我试图比较输入的两个目录的文件名,如果文件名匹配,则说明该文件在两个目录中。但是,当我尝试运行它时,即使我在两个目录中都有相同的文件,也没有任何内容被回显。

回答by Innocent Bystander

Files that are in both Dir1and Dir2:

这两个文件中Dir1Dir2

find "$Dir1/" "$Dir2/" -printf '%P\n' | sort | uniq -d

Files that are in Dir1but not in Dir2:

位于Dir1但不在 中的文件Dir2

find "$Dir1/" "$Dir2/" "$Dir2/" -printf '%P\n' | sort | uniq -u

Files that are in Dir2but not in Dir1:

位于Dir2但不在 中的文件Dir1

find "$Dir1/" "$Dir1/" "$Dir2/" -printf '%P\n' | sort | uniq -u

回答by user3439894

If you want to know what's common to two directories then this is another way with much less coding.

如果您想知道两个目录的共同点,那么这是另一种编码少得多的方法。

#!/bin/bash

comm -12 <(ls -F ) <(ls -F )

See man commfor more information about the commutility.

man comm有关该comm实用程序的更多信息,请参阅。

回答by Barmar

It doesn't work because you're comparing variables that contain the directory prefix. Just remove the prefix before comparing:

它不起作用,因为您正在比较包含目录前缀的变量。只需在比较之前删除前缀:

name1=${file1##*/}
name2=${file2##*/}
if [[ $name1 == $name2 ]]; then
    echo "$name1 exists in both directories"
fi

Also, nested loops seems like an inefficient way to do this. You just need to get the filenames from one directory, and use a simple file existence check for the other directory.

此外,嵌套循环似乎是一种低效的方法。您只需要从一个目录中获取文件名,并对另一个目录使用简单的文件存在检查。

for file in $Dir1/*; do
    name=${file##*/}
    if [[ -f $Dir2/$name ]]; then
        echo "$name exists in both directories"
    fi
done

回答by Mikolaj

I just tested this and it worked:

我刚刚测试了这个并且它有效:

DIR1=$(ls dir1)
DIR2=$(ls dir2)

for i in $DIR1; do
    for j in $DIR2; do
        if [[ $i == $j ]]; then
            echo "$i == $j"
        fi
    done
done

回答by ghoti

Your comparison fails because Dir1/foois not the same as Dir2/foo. Instead, if you change to one directory, your *will expand to just the filenames:

您的比较失败,因为Dir1/fooDir2/foo. 相反,如果您更改为一个目录,您*将扩展为仅文件名:

#!/bin/bash

Dir1=""
Dir2=""

if ! cd "$Dir1"; then
  echo "ERROR: Couldn't find directory $Dir1" >&2
  exit 1
fi

if [[ ! "$Dir2" =~ ^/ ]]; then
  echo "ERROR: Second directory must be a full path." >&2
  exit 1
fi

for file1 in *; do
    if [ -f "$Dir2/$file1" ]; then
        echo "$file1 is contained in both directories"
    fi
done

Note that this only matches file names. If you want to make sure it's really the same file, you should use cmpto compare them.

请注意,这仅匹配文件。如果你想确保它真的是同一个文件,你应该使用cmp来比较它们。