Я не совсем понимаю, почему вы не можете просто использовать cp -r
или rsync -a
для этого, если вы явно не хотите сгладить структуру каталогов, но неважно.
Вы много делаете, чтобы получить путь к подкаталогам:cd
в каталог, pwd
к файлу, а затем прочитать этот файл в переменную. Вместо этого вы можете просто использовать, например.BUrout="$PWD/backup"
($PWD
содержит путь к текущему рабочему каталогу ).
Вы никогда не будете обрабатывать какие-либо файлы, потому что ваш цикл проходит по имени каталога. То, что вы хотите, вероятно, for i in "$r"/*; do
и аналогично во втором цикле.
Всегда двойные кавычки для расширений переменных! Например.if [ "$i" = "$r" ]
(обратите внимание также на одинарную =
, а не на двойную ). См. как " Почему мой сценарий оболочки блокируется пробелами или другими специальными символами? ", так и " Последствия для безопасности, если забыли заключить переменную в кавычки в оболочках bash/POSIX "
В вашем скрипте не должно быть ни одного cd
. Скрипты, которые входят в каталоги и выходят из них, действительно трудно отлаживать.
В остальном синтаксических ошибок нет, логика вроде бы правильная.
Могу ли я предложить что-то вроде этого, в котором по-прежнему используется та же логика циклов и в основном те же тесты, что и в вашем коде, но без вызовов cd
и без необходимости слишком много возиться с именами каталогов:
#!/bin/sh
source="$1"
dest="$2"
mkdir -p "$dest" # creates destination directory if not already exists
for name in "$source"/*; do
if [ -f "$name" ]; then
cp "$name" "$dest"
elif [ -d "$name" ]; then
for name2 in "$name"/*; do
if [ -f "$name2" ]; then
cp "$name2" "$dest"
fi
done
fi
done
Или, используя сокращенный -синтаксис, который нравится некоторым людям:
#!/bin/sh
source="$1"
dest="$2"
mkdir -p "$dest" # creates destination directory if not already exists
for name in "$source"/*; do
[ -f "$name" ] && { cp "$name" "$dest"; continue; }
[ ! -d "$name" ] && continue
for name2 in "$name"/*; do
[ -f "$name2" ] && cp "$name2" "$dest"
done
done
Этот сценарий принимает два аргумента: исходный каталог и целевой/целевой каталог:
$./script mydir some_new_backup_dir
Не предпринимается никаких попыток проверить, не перезапишет ли какая-либо из команд cp
существующий файл в целевом каталоге.
Также обратите внимание, что оба этих скрипта являются /bin/sh
скриптами. Они не используют ничего, характерного для оболочки bash
.
Предполагая, что целевой каталог существует, это более или менее эквивалентно
find source_dir -maxdepth 2 -type f -exec cp {} target_dir ';'
sed '/warning/!d; /error/!d' < file
или
awk '/warning/ && /error/' < file
или
grep warning < file | grep error
sed '/warning/I!d; /error/I!d' < file
gawk -v IGNORECASE=1 '/warning/ && /error/' < file
grep -i warning < file | grep -i error
awk '{l = tolower($0)}; l ~ /warning/ && l ~ /error/' < file
sed '/[wW][aA][rR][nN][iI][nN][gG]/!d; /[eE][rR][rR][oO][rR]/!d' < file
(то преимущество, что оно не зависит от локали; другие могут не совпадать при ПРЕДУПРЕЖДЕНИИ и совпадать при ПРЕДУПРЕЖДЕНИИ вместо этого в некоторых локалях, например ).
Другой, более простой подход к этой проблеме:grep -Ei 'error.warning|warning.error'