Как заменить строку catch на строку чтения сценария bash?

Если ввести команду

$ cat food

вы получите сообщение об ошибке

cat: food: No such file or directory

Если ввести команду

$ cp abc def

вы получите сообщение об ошибке

cp: cannot stat ‘abc’: No such file or directory

Это оченьоченьраспространено для сообщений об ошибках в Unix & Linux. начать с названия программы, выдавшей (т. е. написавшей )их. Итак, когда вы набираете

$ abc:def

в оболочку bash, вполне естественно, что сообщение об ошибке

-bash: abc:def: command not found

начинается с имени bash, потому что bash выдал это сообщение. Одна часть, которая немного сложна заключается в том, что там написано -bashвместо bash. Это происходит потому, что bash является оболочкой, и, в частности,оболочка для входа в систему. По соглашению имена команд входа в систему всегда начинаются с -.

Дополнительные сведения об этом см. в :

.

1
27.09.2019, 12:06
2 ответа

Реализация в вопросе проблематична и неэффективна.

Вы читаете файл построчно и создаете команду sedиз входной строки. Эта команда может вести себя неожиданно, если строка содержит какие-либо специальные символы регулярных выражений, такие как .^$[]и т. д.

Затем вы обрабатываете весь файл с помощью sedодин раз для каждой строки, которую необходимо изменить. Вы можете обрабатывать каждую строку по отдельности вместо многократной обработки всего входного файла.

Я предлагаю использовать awkдля обработки файла и использовать оболочку сценария оболочки, которая обрабатывает временный выходной файл.(awkне поддерживает редактирование места -, например sedили perl.)

#!/bin/bash
filename='myconfigfile.conf'

temp=${filename}.temp

awk '/^[^   ]/ { comment=0 }     # stop commenting if line starts with non-space.
     /^someconfig/ { comment=1 } # start commenting if line starts with "someconfig"
     comment {$0 = "#" $0}       # prepend "#" to whole line ($0)
     { print }' $filename > $temp && mv -f $temp $filename || rm -f $temp

При желании можно добавить правило

     /^[    ]*$/ { comment=0 }   # stop commenting on empty line or space only

, чтобы прекратить комментирование, когда появляется пустая строка или строка, содержащая только пробелы.

Обратите внимание, что [^ ]и [ ]содержат один пробел и один символ табуляции.

Сценарий не обнаруживает какие-либо отступы. Он просто добавляет "#"к тому, что находится в строке (, включая отступ ), пока commentне равен нулю.

1
28.04.2021, 23:29

Зачем использовать sed или awk, если вы уже обрабатываете файл построчно в оболочке? Что-то вроде этого будет работать без использования кучи других программ.

[[ $line =~ '^[[:space:]]' ]] || indent=0
if [[ $line =~ ^someconfig.* || $indent ]]
then
    echo -n "#"
    indent=1
fi
echo "$line"

Отправить вывод цикла во временный файл, а затем mvкак в (тоже очень хорошо )ответ awk:

done <$file >$file.tmp && mv $file.tmp $file

Обычно я предпочитаю, чтобы переименование было связано с &&, чтобы этого не произошло в случае сбоя команды. Кроме того, извините за возможные опечатки -Я печатаю это на телефоне,и трудно писать код на клавиатуре телефона.:)

0
28.04.2021, 23:29

Теги

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