Показать изменения между двумя каталогами - PullRequest
1 голос
/ 13 марта 2011

Хорошо, речь идет о моей пятой ветке по этой теме, потому что я потерял сознание во всех аспектах этого ужасного задания.Я использовал другие решения, которые отлично работали, но не могут быть использованы, например, с помощью команды awk, sed и comm.Вместо этого, я должен сделать это трудным путем.

Я так потерян, на данный момент я даже не делаю это, чтобы передать это, потому что это ноль, так как он истек срок, я рвалмои волосы в течение прошлых 18 часов, пытающихся сделать это только ради того, чтобы сделать это.Буду очень признателен, если вы сможете уберечь меня от попадания пули в мою голову.

Точка назначения: Вы должны написать сценарий оболочки Bash, который поможет сравнить содержимое двух каталогов.Напишите утилиту, которая удовлетворяет следующим требованиям:

  1. Ваш скрипт будет сравнивать имена файлов в двух каталогах и перечислять информацию о именах файлов, которые находятся в одном каталоге, но не в другом.Перечисленная информация будет длинным списком каждого файла, аналогично команде "ls -l".Имена каталогов должны быть указаны, включая любые обязательные абсолютные или относительные пути.
  2. Ваш сценарий будет работать для всех типов файлов, включая каталоги, содержащиеся в указанных каталогах.Сценарий выведет соответствующее сообщение об ошибке, если число переданных ему аргументов не равно 2 или если указанные имена каталогов не являются именами допустимых существующих каталогов.Если выдается сообщение об ошибке, сценарий должен завершиться со статусом выхода 1 (один).В противном случае он должен заканчиваться состоянием выхода 0 (ноль).

Технические характеристики:

  1. Файлы в каталоге, для которого предполагается использовать этот скриптдля работы не имеют разрешения на выполнение, только чтение, которое, если я не ошибаюсь, может отображать только имена файлов, поэтому мы не можем видеть содержимое файла.Я пытался, я получил отказано в разрешении.
  2. Всю информацию, касающуюся этого задания, можно найти здесь: https://cs.senecac.on.ca/~lczegel/BTO120/assign1/assign1.html

Что я сделал:

#!/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 ]

2 голосов
/ 13 марта 2011

Как насчет этого:

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 голос
/ 13 марта 2011
  1. Вы можете получить список всего дерева, используя find. Если вы хотите, чтобы дерево «базировалось» в одном и том же месте, выполните find $the_dir -printf '%P\n' > somewhere. (в противном случае команда find добавляет к каждой строке $the_dir, что затрудняет сравнение)
  2. Вместо того, чтобы проверять каждую отдельную строку, имейте в виду, что если у вас есть файл с обоим содержимым каталога, вы можете просто извлечь из него уникальные строки. Используйте uniq -u для этого. (требование не говорит, что вы должны указать, где находится файл / нет)
  3. Не проверяйте количество аргументов много раз, это либо == 2, либо оно должно входить в предложение else.

Кроме того, комментарий о правах доступа к файлу неверен - если он имеет + r, вы можете прочитать его. Если файл имеет + x, вы можете выполнить его. Видите ли вы файл, зависит только от разрешений, содержащихся в каталоге.

0 голосов
/ 13 марта 2011

Давным-давно существовала программа под названием 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...