列出目录1中但不是目录2中的文件,反之亦然?

嘿,我开始bash shell脚本,我试图做一个脚本分配,当你进入两个目录,它会检查它们是否存在,并根据错误信息显示,如果两个目录存在,它会列出之间的差异当前目录。

$ cd dir-1 $ myshellscript . dir-2 (comparing . aka dir-1 against dir-2) 

输出:

 Files that are in . but not in dir-2 -rw------- 1 ddddd users 1 2011-03-1 01:26 123123123 Files that are in dir-2 but not in . -rw------- 1 ddddd users 1 2011-03-1 01:26 zzzzzzzzzzzz 

我到目前为止似乎没有检测到目录是否存在,也没有列出差异:

 dir-1=$1 dir-2=$2 if [ $# > 2 ] then echo "Usage: compdir dir-name1 dir-name 2" exit 1 elif [ $# < 2 ] then echo "Usage: comdir dir-name1 dir-name 2" elif [ ! -d "$@" ] then echo "/$@ is not a valid existing directory" else exit 0 fi echo $dir-1 echo $dir-2 

我必须使用的命令列表,否则我会使用comm -32 <(ls -la dir-1) <(ls -la dir-2)

 http://dl.dropbox.com/u/20930447/index.html 

Solutions Collecting From Web of "列出目录1中但不是目录2中的文件,反之亦然?"

有点粗糙 – 但我总是使用的最简单的方法是(可以玩差异参数,我通常使用不同的grep

 diff -rcw DIR1 DIR2| grep ^Only 

那么你可以按照你的喜好进行排序和格式化

修改格式(效率较低,因为我们在这里运行diff两次…很容易解决)

 echo files only in $dir1 LST=$(diff ${dir1} ${dir2}| grep "^Only in ${dir1}"| sed 's@^.*: @@') (cd ${dir1}; ls -l ${LST}) echo files only in $dir2 LST=$(diff ${dir1} ${dir2}| grep "^Only in ${dir2}"| sed 's@^.*: @@') (cd ${dir2}; ls -l ${LST}) 

扩展上面的sed表达式:
s =搜索和替换
三个“@”将表达式分开(这是TRADITIONALLY用'/'完成的)
^匹配一行的开头(迫使其余的不匹配在其他地方)。 意味着任何角色
*表示前面的表达式(。==匹配任何字符)0-N次“:”是我在diff输出中匹配的内容“Only in X:”

看看妈妈,没有手 – 现在没有“开始”,开始越来越粗糙了

 XIFS="${IFS}" IFS=$'\n\r' for DIFFLINE in $(diff ${dir1} ${dir2}|grep ^Only); do case "${DIFFLINE}" in "Only in ${dir1}"*) LST1="${LST1} ${DIFFLINE#*:}" ;; "Only in ${dir2}"*) LST2+="${DIFFLINE#*:}" ;; esac done IFS="${XIFS}" echo files only in $dir1 (cd ${dir1}; ls -l ${LST1}) echo files only in $dir2 (cd ${dir2}; ls -l ${LST2}) 

你可能想知道IFS …它需要在bash手册中阅读,但它基本上是字段分隔符字符…默认情况下,它们包含空格,我不希望循环用小数行,只是完整的行 – 所以在循环的持续时间我重写默认的IFS只是换行和回车。

顺便说一句,也许你的教授正在阅读stackoverflow,也许下一个你不会被允许使用分号;-) …(回到“男子bash”…顺便说一句,如果你做'男人bash'在emacs做,使得更容易读IMO)

这几乎工作。 它主要是在两个目录之间有字母相似位置的文件时失败。

 sdiff -s <(ls -1 dir1) <(ls -1 dir2) 

你想要做的基本配置已经在unix-like系统上使用diff工具,或者在Windows上使用cygwin或者GnuWin。 你应该利用这个事实。

如果我有以下内容的目录ab

 ezra@ubuntu:~$ ls -R .: ab ./a: defxyz ./b: ijkxyz 

xyz在每个目录中完全相同。

我可以使用这样的diff命令来实现你想要的:

 ezra@ubuntu:~$ diff ab Only in a: d Only in a: e Only in a: f Only in b: i Only in b: j Only in b: k 

如果我添加一个新文件到每个目录(名为new ),这是不同的,我得到以下内容:

 ezra@ubuntu:~$ diff ab Only in a: d Only in a: e Only in a: f Only in b: i Only in b: j Only in b: k diff a/new b/new 1c1 < ezraa --- > ezra 

也就是说,它甚至会告诉你如何以及文件差异在哪里出现。 当然,如果你不想或不需要这个功能,你可以自由地使用它。

您还得到以下内容:

 ezra@ubuntu:~$ diff ac diff: c: No such file or directory 

随着这个由diff完成的程序的繁重工作,你所写的大部分内容都将解析这个命令的输出,然后按你认为合适的方式操作或输出它。

当你这样做时, awksed可能会特别感兴趣。

 awk '{a[$0]++}END{print "some message"; for(i in a)if(a[i]<2){print i}}' <(ls -1 dir2) <(ls -1 dir1) 

概念验证

 $ ls -1 dir1 file1.txt file2.txt file3.txt file4.txt file5.txt $ ls -1 dir2 file1.txt file3.txt file4.txt $ awk '{a[$0]++}END{print "Files in dir1 but NOT in dir2"; for(i in a)if(a[i]<2){print i}}' <(ls -1 dir2) <(ls -1 dir1) Files in dir1 but NOT in dir2 file5.txt file2.txt 

我喜欢用diff来比较:

 diff <(ls -1 dir1) <(ls -1 dir2) | awk '{if ($1==">") print "in dir 2: "$2; if($1=="<") print "in dir 1: "$2;}' 

你也可以阅读分析:

 diff <(ls -1 $dir1) <(ls -1 $dir2) | while read status filename do [ "$status" == "<" ] && echo "in dir 1: $(ls -l $dir1/$filename)" [ "$status" == ">" ] && echo "in dir 2: $(ls -l $dir2/$filename)" done 
 echo "Files that are in $dir1 but not $dir2" for i in "$dir1/"*; do [[ -e "$dir2/$i" ]] || (cd "$dir1"; ls -l "$i") done echo 

这是其中的一半。

[[ ... ]]替换为[ ... ]或者test ...如果不使用Bash。