У меня есть две папки со схожими структурами подпапок, которые я хотел бы сравнить. Например:
A
├── child-1
├── child-2
├── child-3
├── child-4
├── child-5
и
B
├── child-1-some-text
├── child-2-more-text
├── child-3-nothing
├── child-6-random-text
├── child-7-more-random-text
Я хотел бы перечислить все те подпапки, из A
которых есть префикс для подпапки, B
и перечислить также соответствующие подпапки B
. Ожидаемый результат
child-1 -- child-1-some-text
child-2 -- child-2-more-text
child-3 -- child-3-nothing
Второстепенное требование: если несколько совпадений B
, то должно появиться сообщение об ошибке / предупреждение.
Мое решение :
cd A
for f in `ls -d */`;
do
cd B;
new_dirs=(`ls -1d $f*`);
cd -;
if [ ${#new_dirs[@]} -eq 0 ]
then
## DO_Nothing
continue;
elif [ ${#new_dirs[@]} -gt 1 ]
then
echo "Multiple matches to $f";
continue;
else
echo "Unique Match found to $f -- ${new_dirs[0]}";
continue;
fi;
done
Проблема:
Для тех значений $f
, в которых нет соответствующих подпапок B
, конструкция массива выдает ошибку. например:
ls: не может получить доступ к 'child-4 *': нет такого файла или каталога
Вопрос
- Как избавиться от этих ошибок?
- Есть ли лучший способ достичь цели, чем в моем коде?
Заранее спасибо!
diff -rq DIR1 DIR2
для сравнения не только структуры каталогов, но и содержимого файлов.Ответы:
Лучший способ
Не разбирайся
ls
; вместо этого используйте шарики. На самом деле вы уже используете шарики, просто оборачивая ихls
, что бессмысленно. Вам просто нужноnullglob
включить, когда нет совпадений.Также избегать
cd
упрощает вещи.Вывод:
Я добавил,
B/child-3-something
чтобы проверить вторичное требование. Это создает структуру каталогов для тестирования:Кстати, ShellCheck очень полезен для поиска проблем в сценариях оболочки.
источник
shellcheck
пакета будет самой безопасной]ShellCheck
. Мне понравилась часть, где она не только сообщает вам ваши ошибки, но и дает советы! @ Xen2050, про загрузку, я только что установилshellcheck
с помощьюapt
и затем отключил сеть. Вроде работает без интернета .При вызове
ls
несуществующей папки выдается сообщение об ошибке, с которым вы столкнулись. Самый простой способ это просто игнорировать это, заменив строку 5 в сценарии с этим:new_dirs=(`ls -1d $f* 2> /dev/null`);
.источник
t=(`echo ok; echo err 1>&2`)
$ t (или${t[@]}
), содержит только ok, ошибка отображается в терминале, но не сохраняется в любом случае. Или в моем тесте есть что-то смешное?