Выписывание только файлов, существующих в одном каталоге или другой или наличие другого размера или время последних, изменяют

Я пишу сценарий, где я должен сравнить 2 каталога (рекурсивно) и выписать только файлы, если у них есть другой размер, или время изменяют (DD MM YY HH:MM) или если файл существует только в одном каталоге.

Вывод быть в формате:

<dir1>:<local-path> <size> <last-modify> <dir2>:<local-path> <size> <last-modify>

Если файл существует только в одном каталоге:

<dir1>:<local-path> <size> <last-modify>

или

<dir2>:<local-path> <size> <last-modify>

До сих пор мне удалось получить мои данные в указанном использовании формата:

find dir1 -type f -exec stat -c '%n %s %y' {} \; | sed 's,^[^/]*/,,' | sed 's/\:[^:]*$//' | sort # > dir1.txt
find dir2 -type f -exec stat -c '%n %s %y' {} \; | sed 's,^[^/]*/,,' | sed 's/\:[^:]*$//' | sort # > dir2.txt

Который дает мне 2 заказанных списка файлов в данных каталогах и подкаталогах и их размере и в последний раз измененной метке времени.

Теперь я должен так или иначе сравнить их и получить их к указанному формату выше. Я пытался использовать разность-y, но она выдерживает сравнение линию за линией, но мне нужно то же имя к тому же имени. Я также попробовал коммуникацию, но не знайте, как преобразовать тот выходной формат.

Какие-либо идеи?

1
задан 18 November 2016 в 18:39

2 ответа

Я думаю, что попытался бы соединить что-то базирующееся вокруг использования rsync в режиме пробного прогона (--dry-run или -n).

Для иллюстрирования, данный:

$ tree -Ds Adir/ Bdir/
Adir/
├── [       4096 Nov 19  9:36]  sub1
│   ├── [         35 Nov 19  9:35]  common
│   └── [         23 Nov 19  9:36]  onlyA
├── [       4096 Nov 19  9:41]  sub2
│   ├── [         35 Nov 19  9:35]  common
│   ├── [         44 Nov 19  9:44]  newerA
│   ├── [         44 Nov 19  9:37]  olderA
│   └── [          6 Nov 19 10:36]  size
└── [       4096 Nov 19  9:35]  sub3
    └── [         35 Nov 19  9:35]  common
Bdir/
├── [       4096 Nov 19  9:46]  sub1
│   └── [         35 Nov 19  9:35]  common
├── [       4096 Nov 19 10:36]  sub2
│   ├── [         35 Nov 19  9:35]  common
│   ├── [         44 Nov 19  9:38]  newerA
│   ├── [         44 Nov 19  9:44]  olderA
│   └── [         24 Nov 19 10:36]  size
└── [       4096 Nov 19  9:40]  sub3
    ├── [         35 Nov 19  9:35]  common
    └── [         23 Nov 19  9:40]  onlyB

6 directories, 14 files

затем мы можем перечислить файлы, которые имеют различные размеры или время изменения следующим образом:

$ rsync -aOn --delete --itemize-changes Adir/ Bdir/
*deleting   sub3/onlyB
>f+++++++++ sub1/onlyA
>f..t...... sub2/newerA
>f..t...... sub2/olderA
>f.s....... sub2/size

[Строка изменения действительно не имеет значения в наших целях, но например *deleting указывает, что sub3/onlyB не присутствует в исходном каталоге; s указывает на различие в размере; t указывает на различие во время изменения.]

, К сожалению, это, кажется, не возможно получить, фактические метки времени непосредственно от rsync производят, но мы можем просто прочитать список файлов и статистику соответствующие файлы в каждом каталоге:

#!/bin/bash

dirA="$1"
dirB="$2"

rsync -aOn --itemize-changes --delete "$dirA"/ "$dirB"/ | while read -r c f ; do
  printf '%s:%s  ' "$dirA" "$(cd "$dirA" && stat -c '%n %s %y' "$f" 2>/dev/null || printf '(none) - - - -')"
  printf '%s:%s\n' "$dirB" "$(cd "$dirB" && stat -c '%n %s %y' "$f" 2>/dev/null || printf '(none) - - - -')"
done

, который мы можем использовать следующим образом

$ ./rstat.sh Adir Bdir | column -t
Adir:(none)       -   -           -                   -      Bdir:sub3/onlyB   23  2016-11-19  09:40:12.253318393  -0500
Adir:sub1/onlyA   23  2016-11-19  09:36:52.220421434  -0500  Bdir:(none)       -   -           -                   -
Adir:sub2/newerA  44  2016-11-19  09:44:45.953236221  -0500  Bdir:sub2/newerA  44  2016-11-19  09:38:33.270838033  -0500
Adir:sub2/olderA  44  2016-11-19  09:37:41.675642039  -0500  Bdir:sub2/olderA  44  2016-11-19  09:44:45.953236221  -0500
Adir:sub2/size    6   2016-11-19  10:36:31.460487036  -0500  Bdir:sub2/size    24  2016-11-19  10:36:31.460487036  -0500
1
ответ дан 7 December 2019 в 15:44

Я думаю, что Вы уже закончили, вот ниже для:

Если файл существует только в directory1 (рассматривающий любые различия в имени, размере или время изменения:

grep -Fxvf dir2.txt dir1.txt > inDir1Only

Или Если файл существует только в directory2:

grep -Fxvf dir1.txt dir2.txt > inDir2Only

Таким образом в конце для Вашего вопроса "выписывают только файлы, если у них есть другой размер, или время изменяют (DD MM YY HH:MM)", просто конкатенируйте два выше результатов, как следующее:)

принятие inDir1Only и inDir2Only содержание как следует:

$ cat inDir1Only
    c.txt 26 2016-11-04 14:23
    b.txt 26 2016-11-04 14:23
$ cat inDir2Only
    b.txt 57 2016-11-04 18:20
    a.txt 14 2016-11-04 18:11

с тех пор Вас желаемый вывод был бы так же как ниже после выполнения ниже awk команда,

$ awk 'NR==FNR{seen[$1]=$0;next} {
    print "inDir1Only:"$0, ($1 in seen) ?"inDir2Only:"seen[$1]:"";seen[$1]=""}
END{
    for(x in seen) if (seen[x]!=NULL) print "inDir2Only:"seen[x]
}' inDir2Only inDir1Only

inDir1Only:c.txt 26 2016-11-04 14:23 
inDir1Only:b.txt 26 2016-11-04 14:23 inDir2Only:b.txt 57 2016-11-04 18:20
inDir2Only:a.txt 14 2016-11-04 18:11
0
ответ дан 7 December 2019 в 15:44

Другие вопросы по тегам:

Похожие вопросы: