Создание ответов выше чиновника: да, это работает. Много людей делает точно это (самостоятельно включенный), но существует включенная кривая обучения.
Резервное копирование с помощью gzip
выполняется не в каталог, а в другой файл:
gzip < file.in > file.out
или в вашем случае:
filelocation=/home/user/image.img
backuplocation=/home/image.img.gz
gzip < "$filelocation" > "$backuplocation"
на основе этого можно сделать:
gunzip < "$backuplocation" > /some/new/location/image.img
-121--16â1- U-Boot делает именно то, что должно (замалчивая вывод) с помощью следующей команды:
# define CONFIG_EXTRA_ENV_SETTINGS\
"silent = 1\0
кажется, что это происходит только в моей системе.
-121--60988- При условии, что имена файлов не содержат :\[ *?
, можно использовать GLOBIGNORE
. Просто отформатируйте список каталогов соответствующим образом. Например:
$ cat names.txt
folder1
folder3
Это очень легко преобразовать в двоеточие разделенный список:
$ paste -s -d : names.txt
folder1:folder3
Так что теперь вы можете установить, что в качестве значения GLOBIGNORE:
GLOBIGNORE=$(paste -s -d : ../names.txt)
И приступить к их удалению нормально:
rm -r -- *
Я только что протестировал это на Linux с 300 каталогами и он работал идеально.
Простой подход - это список всех файлов и игнорировать те, которые находятся в файле списка. Обратите внимание, что я организующуюся для переменной IGNORE_LIST
, чтобы начать и заканчиваться новой строкой, чтобы я мог проверить, включен ли $ x
простым способом (просто проверяя, что IGNORE_LIST
содержит $ x
не работает, поскольку он также будет соответствовать файлам, имя которого представляет собой подстроку элемента списка игнорирования).
newline='
'
ignore_list="$newline$(cat list.txt)$newline"
cd target_folder
for x in * .[!.]* ..?*; do
case "$x" in *"$newline"*) continue;; esac # sanity check: if the file name contains a newline, leave it alone
case "$ignore_list" in
*"$newline$x$newline"*) echo "Skipping $x";;
*) rm -rf -- "$x";
esac
done
Как насчет этого?
find ./target_folder/ \
-mindepth 1 \
-maxdepth 1 \
-type d \
-not -name 'anything[0-9]*' \
-exec rm -rf {} \;
Позвольте мне объяснить:
-Mindepth 1
гарантирует, что вы не совпадаете ./ TAVE_FOLDER /
-MAXDEPTH 1
гарантирует, что вы не соответствуете любым подпапкам. -Type d
говорит найти только для матча каталогов, а не файлов. -NOT -NAME 'НИЧЕГО [0-9] * «
исключает из шаблона все, что соответствует шаблону. Довольно очевидно, что один. --eexec
должен использоваться с осторожностью, особенно когда он включает в себя RM
.
Вы должны всегда тестируйте это, используя ECHO
, прежде чем идти вперед и RM -RF
Thanging так. Найти
Может быть сложно к \;
при использовании EXEC. Вы можете прочитать найти
ручную страницу для получения дополнительной информации. Это очень удобно инструмент .
Вы можете сделать это в Bash, как
for folder in /target_folder/*/
do
folder=${folder%/}
if ! grep -qx "${folder##*/}" folders_list.txt
then
rm -rf "$folder"
fi
done
С zsh
(обратите внимание, что GLOBIGNORE
не зависит от bash, ни bash
, ни zsh
установлены во FreeBSD по умолчанию, но доступны оба):
(cd /target_folder || exit
all_dirs=(*(/))
to_exclude=(${(f)"$(<names.txt))"})
rm -rf -- ${all_dirs:|to_exclude})
Особые особенности zsh
:
* (/)
. (/)
- квалификатор glob , который означает выбор только файлов типа в каталоге . $ (: расширяется до содержимого (без завершающих символов новой строки) файла
(происходит из ksh
, bash
также он есть, но выполняет форк для чтения содержимого файла
там).
$ {(f) ...}
. Это флаг раскрытия параметра , который разделяет раскрытие «$ (...)»
на перевод строки. Для bash
вам нужно будет сделать что-то вроде: IFS = $ '\ n'; set -f; to_exclude = ($ ( вместо этого.
$ {A: | B}
расширяется до элементов массива $ A
, которых также нет в массиве $ B
. Другое решение, совпадает с началом и концом имен папок:
IFS=$'\n'
folders="""folder1
folder2"""
for folder in *; do
found=0
if [ -d "$folder" ]; then
for i in $folders; do
if [ $(echo "$folder" | grep -c -E "^$i\$") -eq 1 ]; then
found=1
fi
done
if [ $found -ne 1 ]; then
echo "$folder found and deleted."
rm -rf "$folder"
fi
fi
done
В системе GNU или FreeBSD вы можете:
cd /target_folder &&
printf '%s\0' * | grep --null -vxFf names.txt | xargs -r0 rm -rf