Как пропустить файл в sed, если он содержит регулярное выражение?

В настоящее время я использую следующую упрощенную команду для удаления конечных пробелов и добавления новой строки в конец файла, где это необходимо:

find . -type f -exec sed -i -e 's/[ \t]\+\(\r\?\)$/\1/;$a\' {} \+ 

Как вы быстро увидите, это имеет две проблемы: он изменит двоичные файлы и добавит новую строку в конец файлов с разделителями строк . Эти изменения легко отменить или пропустить при совершении в git gui или т. П., Но я хотел бы свести к минимуму количество возвращающихся данных. С этой целью:

Есть ли способ пропустить весь файл, если какая-либо строка соответствует регулярному выражению в sed ?

* Я знаю, что могут быть двоичные файлы без ␀ символов, и могут быть файлы с намеренно смешанными переводами строк или ␀s. Но я ищу решение, требующее минимального вмешательства человека. Я мог бы, вероятно, перечислять все расширения файлов, над которыми я хотел бы работать, но это был бы очень длинный список, который нужно было бы постоянно проверять, и из-за конфликтов имен все равно было бы возможно, что бинарные файлы проскальзывают.

Сложное обходное решение :

 while IFS= read -r -d '' -u 9 do if [[ "$(file -bs --mime-type -- "$REPLY")" = text/* ]] then sed -i -e 's/[ \t]\+\(\r\?\)$/\1/;$a\' -- "$REPLY" else echo "Skipping $REPLY" >&2 fi done 9< <(find . -type f -print0) 

3 Solutions collect form web for “Как пропустить файл в sed, если он содержит регулярное выражение?”

Если вы доверяете точке зрения git на то, что является двоичным файлом или нет, вы можете использовать git grep для получения списка не двоичных файлов. Предполагая, что t.cpp является текстовым файлом, а ls является двоичным, оба отмечены:

 $ ls t.cpp ls $ git grep -I --name-only -e '' t.cpp 

Опция -I означает:

-I
Не сопоставляйте шаблон в двоичных файлах.

Чтобы объединить это с выражением sed :

 $ git grep -I --name-only -z -e '' | \ xargs -0 sed -i.bk -e 's/[ \t]\+\(\r\?\)$/\1/;$a\' 

( -z / xargs -0 чтобы помочь со странными именами файлов.)

--cached страницу git grep man для других полезных опций – --no-index или --cached может помочь в зависимости от того, какой набор файлов вы хотите использовать.

Вот скрипт Perl, который выполняет итерации по своим аргументам (которые должны быть именами файлов) и добавляет новую строку для каждого файла, который не заканчивается в новой строке. Файлы, содержащие нулевой байт, пропускаются. Файлы, которые уже заканчиваются в новой строке, не изменяются. Файлы, содержащие CR, получают CRLF, другие получают только LF. Непроверенные.

 #!/usr/bin/env perl foreach my $f (@ARGV) { open F, "<", $f or die; my $last = undef; my $cr = 0; while (<>) {if (/\0/) {undef $last; break} $last = $_; ++$cr if /\r$/} close F; if (defined $last && $last !~ /\n\Z/) { open F, ">>", $f or die; print($cr ? "\r\n" : "\n"); close F or die; } } 

Есть ли способ пропустить весь файл, если какая-либо строка соответствует регулярному выражению в sed?

Да, есть.

 # test case for skipping file if a sed regex match succeeds echo 'Hello, world!' > hello_world.txt cat hello_world.txt ls -li hello_world.txt sed -i -e '/.*Hello.*/{q;}; s/world/WORLD/g' hello_world.txt # skips file sed -i -e '/.*HeLLo.*/{q;}; s/world/WORLD/g' hello_world.txt 
  • Удалите обе строки, если значения столбца A повторяются в следующей строке
  • grep для извлечения подстроки из огромной строки
  • цикл через выход одной команды и использовать в другой команде
  • Выберите строки, начинающиеся с определенных номеров
  • Узнайте, на какой строке в текстовом файле соответствует слово
  • Сбросьте шаблон слова в конце строки, используя sed
  • Bash - Конвертировать символ escape-символа в BBCode
  • Почему sed дает мне ошибку в отношении неиспользуемого `s '?
  • Каким образом можно фильтровать текстовый файл для удаления пустых строк?
  • sed или tr однострочный, чтобы удалить все числовые цифры
  • Как найти и заменить только определенное слово (которое находится в конце файла) с помощью команды оболочки?
  • Использование CSV-строки в качестве параметров команды
  • Linux и Unix - лучшая ОС в мире.