Intereting Posts
Как установить libunity-dev в Debian Jessie? Связывание ключей Ci и TAB с различными командами в терминальных приложениях через .inputrc Как отформатировать жесткий диск с защитой от записи в Linux? piping ssh к сценарию оболочки и не видеть stdin echo Как выполнить скрипт на удаленном сервере после входа в систему через ssh как перевести скрипт bash «эхо-сообщения» автоматический метод Когда su и sudo используют разные пароли? Как выполнить полный вывод двух произвольных команд одновременно Как сделать поиск Nautilus полезным вне / дома? прослушать два IP-адреса для размещения 2-х сайтов с SSL Команда выполняется по-разному в зависимости от того, как вошел в систему? Выбор правильного распознавателя для определенной области bash script – logrotate выводит переименование Незначительная проблема рендеринга шрифтов в Linux Mint 18.1 (Cinnamon) Как получить уведомление от источника энергии, когда ИБП включен

Передача обычных файлов только на `sed -i`

Я использую GNU sed 4.2.2, и после поиска не удается найти причину, по которой sed ведет себя странно в некоторых ситуациях:

У меня есть каталог со следующим:

 foofile.txt barfile.txt bazfile.txt config/ 

Дело 1

 sed -i 's/foo/bar/g' *.txt 

Это работает, как я ожидаю. Он заменяет все «foo» на «bar» s в трех обычных файлах.

Случай 2

 sed -i 's/foo/bar/g' * sed: couldn't edit config: not a regular file 

Он заменяет «foo» на «bar» в barfile.txt и bazfile.txt , но не в foofile.txt . Я предполагаю, что он просматривает список файлов, расширенный из * алфавитном порядке, и когда он попадает в config/ это ошибки и выходы. Есть ли способ заставить sed игнорировать ошибки и продолжить обработку файлов?

Случай 3

 for file in $(find . -maxdepth 1 -type f); do sed -i 's/foo/bar/g' <"$file"; done sed: no input files sed: no input files sed: no input files 

Может кто-нибудь объяснить, почему sed это делает? Почему он говорит, что нет входного файла, когда ему дают?

Я знаю, что могу использовать следующее, но я спрашиваю, почему sed действует таким образом, а не как решить этот вариант использования.

 find . -maxdepth 1 -type f -exec sed -i 's/foo/bar/g' {} \; 

Это нормальное поведение. В обоих случаях sed выходит с error code 4 … для info sed :

 4 An I/O error, or a serious processing error during runtime, GNU 'sed' aborted immediately. 

и в обоих случаях сообщения не требуют пояснений. Не уверен, что неясно, но для записи: в первый раз, когда он ошибается, потому что он не может редактировать каталог, а во второй раз он жалуется, потому что он не может редактировать stdin на месте, ему нужен файл (т. Е. Удалить перенаправление перед $file )
Правильный способ сделать это с помощью find , как вы отметили, через -exec ...
С помощью globs вам нужно будет использовать цикл и проверить, является ли вход обычным файлом перед запуском sed . Или, если вы пользователь zsh , вы можете просто сделать:

 sed -i 's/foo/bar/g' *(.) 
  • Случай 2:

    Избегайте этого каталога с помощью find :

     sed -i 's/foo/bar/g' `find . -maxdepth 1 -type f` 
  • Случай 3:

    Проблема заключается в <"$file" в цикле, который превращает файл в поток, поэтому sed никогда не видит имя файла. Просто удалите это < :

     for file in $(find . -maxdepth 1 -type f); do sed -i 's/foo/bar/g' "$file"; done