显示两个目录之间的更改

时间:2011-03-12 22:21:00

标签: linux bash shell unix

好的,这是我关于这个主题的第五个主题,因为我在这个可怕任务的各个方面都失败了。我已经使用了其他完美但无法使用的解决方案,例如使用awk命令,sedcomm。相反,必须采取这种方式。

我很迷茫,此时我甚至没有把它交给它,因为它已经过了约会,因为它已经过了截止日期,过去18个小时我一直在试着弄掉头发完成只是为了完成它。非常感谢,如果你能救我把子弹放到我脑海里。

分配点:您要编写一个Bash shell脚本,它有助于比较两个目录的内容。编写满足以下要求的实用程序:

  1. 您的脚本将比较文件名 在两个目录和列表中 有关文件名的信息 在一个目录中但不在另一个目录中。 列出的信息将是一个 每个文件的长列表,类似 到“ls -l”命令。该 必须指定目录名称, 包括任何必需的绝对或 相对路径。
  2. 您的脚本适用于各种类型 文件,包括目录 包含在指定的 目录。该脚本将打印出来 一个适当的错误消息,如果 传递给它的参数数量是 2以外的东西,或者如果是 指定的目录名称不是 有效现有目录的名称。 如果发出错误消息,则 脚本应该以退出结束 状态为1(一)。否则,它 应该以退出状态0结束 (零)。
  3. 规格:

    1. 目录中的文件 脚本应该工作不要 有执行权限,只读 如果我没有弄错,那只能 显示文件名,所以我们看不到 文件内容。我试过了,我明白了 许可被拒绝。
    2. 有关此内容的所有信息 分配可以在这里找到: https://cs.senecac.on.ca/~lczegel/BTO120/assign1/assign1.html
    3. 我做了什么:

      #!/bin/bash
      
      if [ ! -d $1 ]
         then
            echo $1 is not a valid existing directory >&2
            exit 1
         elif [ ! -d $2 ]
            then
            echo $2 is not a valid existing directory >&2
               exit 1
         elif [ $# = 0 ]
            then
               echo Usage: compdir dir-name1 dir-name2 >&2
               exit 1
         elif [ $# = 1 ]
            then
               echo Usage: compdir dir-name1 dir-name2 >&2
               exit 1
         elif [ $# = 2 ]
            then
      
               ls -a $1 > temp1
               ls -a $2 > temp2
      
               cat temp1 |
               while read input
               do
                  grep -Fvf temp1 temp2 > temp1_diff
               done
      
               cat ~temp2 |
               while read input
               do
                  grep -Fvf temp2 temp1 > temp2_diff
               done
      
               #Files that are in $1 but not in $2
               cat temp1_diff |
               while read input
               do
                  Files that are in $1 but not in $2
                  cd $2
                  ls -la `cat ../temp1_diff`
               done
      
               cd ..
               echo -e
      
               #Files that are in $2 but not in $1
               cat temp2_diff |
               while read input
               do
                  Files that are in $2 but not in $1
                  cd $1
                  ls -la `cat ../temp2_diff`
               done
      
         elif [ $# = 3 ]
            then
               echo Usage: compdir dir-name1 dir-name2 >&2
               exit 1
         else
               echo Usage: compdir dir-name1 dir-name2 >&2
               exit 1
      fi
      

      我遇到的问题:

      1. 它不会写任何文件 有任何字符,如点或 空间或其中的任何东西 temp1_diff和temp2_diff。
      2. 我无法得到回声一次回声 即使它在循环之前或循环中。
      3. 我得到的不断是错误 导航到$ 1或$ 2等。

3 个答案:

答案 0 :(得分:2)

如何以这种方式接近它:

for f in `ls -a $1`
do
    if [ -r $1/$f ] && [ ! -x $1/$f ] && [ ! -r $2/$f ]
        then 
            echo "$f Not in other dir"

现在您知道该文件位于您的第一个目录中,但不是第二个目录。

编辑:已更改为检查第一个目录中的文件是否可读+根据相关规格不可执行 - 这将告诉您它是否不在具有读取权限的其他目录中

答案 1 :(得分:1)

  1. 您可以使用find列出整个树。如果您希望树“基于”在同一个地方,请执行find $the_dir -printf '%P\n' > somewhere。 (否则发现将$the_dir添加到每一行,使得比较更难)
  2. 不要单独检查每一行,请记住,如果您的文件中列出了两个目录内容,则可以从中获取唯一的行。使用uniq -u即可。 (要求并没有说你必须告诉文件在哪里/不是)
  3. 不要多次检查参数计数,它要么是== 2,要么应该进入else子句。
  4. 此外,关于文件权限的评论是错误的 - 如果它有+ r,你可以阅读它。如果文件有+ x,则可以执行它。您是否看到该文件仅取决于包含目录的权限。

答案 2 :(得分:0)

曾几何时,有一个名为dircmp的程序执行了很多请求 - 主要区别在于它没有为找到的文件执行ls -l格式列表但没有另一个目录。这将需要一些黑客攻击。前段时间,很明显dircmp正在走向恐龙的道路,但是有足够的生物学家来创造一个适合我的版本。如果您必须处理包含空格,制表符或换行符的文件名,它可能会给您一些问题,但否则可能会有用。

以下是您的作业的不完整答案,但至少是一个可行的起点。

#!/bin/sh
#
#       @(#)$Id: dircmp.sh,v 1.6 2003/03/12 08:29:13 jleffler Exp jleffler $
#
#       Simulation of the much-loved dircmp(1) script, with extensions.

arg0=$(basename $0 .sh)

error(){
        echo "$arg0: $*" 1>&2
        exit 1
}

dflag=0 # Files that are different
mflag=0 # Files that are missing in one or the other
sflag=0 # Files that are the same in both (or directories, or otherwise special)
while getopts dms flag
do
        case "$flag" in
        (d) dflag=1;;
        (m) mflag=1;;
        (s) sflag=1;;
        (*) echo "Usage: $arg0 [-dms] dir1 dir2" 1>&2; exit 1;;
        esac
done
shift $(expr $OPTIND - 1)

# If user set no flags, set them all (traditional behaviour of dircmp).
if [ $sflag = 0 ] && [ $dflag = 0 ] && [ $mflag = 0 ]
then dflag=1; mflag=1; sflag=1
fi

if [ $# != 2 ]
then echo "Usage: $arg0 [-dms] dir1 dir2" 1>&2; exit 1 
elif [ ! -d "$1" ]
then error "$1 is not a directory"
elif [ ! -d "$2" ]
then error "$2 is not a directory"
fi

tmp="${TMPDIR:-/tmp}/dc.$$"
trap "rm -f \"$tmp\".?; exit 1" 0 1 2 3 13 15

(cd "$1" 1>&2 && find . -print | sort) > "$tmp".1
(cd "$2" 1>&2 && find . -print | sort) > "$tmp".2

{
if [ $mflag = 1 ]
then
        comm -23 "$tmp".1 "$tmp".2 > "$tmp".3
        comm -13 "$tmp".1 "$tmp".2 > "$tmp".4 
        if [ -s "$tmp".3 ] || [ -s "$tmp".4 ]
        then
                long=$(awk '{if(length($0) > len) { len = length($0); }}
                                END { print 2 * len + 6; }' "$tmp".3 "$tmp".4)
                echo "Files in $1 only and in $2 only"
                echo
                pr -w$long -l1 -t -m "$tmp".3 "$tmp".4
                echo
        fi
        rm -f "$tmp".3 "$tmp".4
fi

if [ $sflag = 1 ] || [ $dflag = 1 ]
then
        comm -12 "$tmp".1 "$tmp".2 > "$tmp".5
        if [ -s "$tmp".5 ]
        then
                case $sflag$dflag in
                (11) echo "Comparison of files in $1 and $2";;
                (01) echo "Files which differ in $1 and $2";;
                (10) echo "Files which are the same in $1 and $2";;
                esac
                echo
                cat "$tmp".5 |
                while read file
                do
                        if [ -f "$1/$file" ] && [ -f "$2/$file" ]
                        then
                                if cmp -s "$1/$file" "$2/$file"
                                then [ $sflag = 1 ] && echo "same                $file"
                                else [ $dflag = 1 ] && echo "different           $file"
                                fi
                        elif [ $sflag = 0 ]
                        then continue
                        elif [ -d "$1/$file" ] && [ -d "$2/$file" ]
                        then echo "directory           $file"
                        elif [ -b "$1/$file" ] && [ -b "$2/$file" ]
                        then echo "block special       $file"
                        elif [ -c "$1/$file" ] && [ -c "$2/$file" ]
                        then echo "character special   $file"
                        elif [ -p "$1/$file" ] && [ -p "$2/$file" ]
                        then echo "named pipe          $file"
                        else echo "***dubious***       $file"
                        fi
                done 
                echo
        fi
fi
} |
uniq

rm -f $tmp.?
trap 0