
У меня есть структура папок, которая (плохо) поддерживалась рядом автоматизированных заданий. Одним из побочных эффектов этих заданий, по-видимому, является то, что они создают дублирующие имена папок (и, следовательно, дублирующие изображения).
У меня на этом сервере размещено около 50 ГБ изображений, и по консервативной оценке не менее 10% из них дублируются. Я нахожусь в процессе миграции на новую инфраструктуру и хотел бы дедуплицировать файлы и папки.
Дана следующая структура каталогов
images/New_Site/Food
images/New_Site/Food/Content
images/New_Site/Food/Content/Content
images/New_Site/Food/Content/Waterfall
images/New_Site/Food/Food
images/New_Site/Food/Food/Content
images/New_Site/Food/Food/Recipes
images/New_Site/Food/Recipes
images/New_Site/Food/Recipes/Recipes
images/New_Site/Home
images/New_Site/Home/Home
images/New_Site/Kids
images/New_Site/Kids/Kids
images/New_Site/Men
images/New_Site/Men/Men
images/New_Site/New_Site
images/New_Site/New_Site/Baby
images/New_Site/New_Site/Beauty
images/New_Site/New_Site/Corporate
images/New_Site/New_Site/Corporate/About
images/New_Site/New_Site/Corporate/Careers
images/New_Site/New_Site/Corporate/Education
images/New_Site/New_Site/Corporate/Legal
images/New_Site/New_Site/Food
Я хочу создать скрипт, который будет копировать только следующие папки (без рекурсии)
images/New_Site/Food
images/New_Site/Food/Content
images/New_Site/Food/Content/Waterfall
images/New_Site/Food/Recipes
images/New_Site/Home
images/New_Site/Kids
images/New_Site/Men
В текущей дублированной структуре содержится более 2200 папок, поэтому ручная очистка не является эффективным повторяющимся процессом.
Чтобы усложнить ситуацию, мне нужно перенести дедуплицированные элементы из AIX в среду Windows 2012 R2. Я могу использовать Putty SCP для копирования файлов между серверами или создать zip-архив (хотя и на 50 ГБ, не уверен, что архив — хорошая идея).
Мой подход заключается в том, чтобы найти все папки, удалить все папки, которые имеют дублирующее имя сразу после предыдущего имени, используя '/' в качестве разделителя. Так что логически я могу это сделать, но не могу перевести это в команду grep какого-либо рода. Любая помощь будет высоко оценена.
решение1
Это не grep, но вот скрипт bash, который должен дать вам то, что вы хотите:
#!/bin/bash
srcdir=$1
destdir=$2
subdir=${3:-$destdir}
depth=$((${4:-0} + 1))
srcdirbase=${srcdir##*/}
for subdirdir in $srcdir/*/
do
fixdir=${subdirdir%*/}
fixbase=${fixdir##*/}
if [ "$fixbase" != "*" -a "$fixbase" != "$srcdirbase" ]; then
newsubdir=$subdir/$fixbase
echo -e "mkdir \"$newsubdir\" && cp \"$fixdir/*\" \"$newsubdir\""
if [ $depth -lt 20 ]; then
./$0 "$fixdir" "$destdir" "$newsubdir" $depth
fi
fi
done
Если вы дадите ему имя snowflake.sh
, то вы можете назвать его так:
(echo "#\!$SHELL"; ./snowflake.sh <source_dir> <dest_dir>) > bugfix.sh
Замените <source_dir>
и <dest_dir>
на фактические пути, которые у вас есть.
решение2
Как насчет использования этого:
grep --invert-match '/(.+)/\1'
Или для соответствия вашему измененному тестовому случаю
grep --invert-match '(.+)/\1'