Соответствует строке в текстовом файле, содержащей два ключевых слова

Я не совсем понимаю, почему вы не можете просто использовать 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 ';'

0
28.01.2020, 13:16
2 ответа

С учетом регистра:

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

(то преимущество, что оно не зависит от локали; другие могут не совпадать при ПРЕДУПРЕЖДЕНИИ и совпадать при ПРЕДУПРЕЖДЕНИИ вместо этого в некоторых локалях, например ).

2
28.04.2021, 23:25

Другой, более простой подход к этой проблеме:grep -Ei 'error.warning|warning.error'

0
28.04.2021, 23:25

Теги

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