Hex Code для '(' в Bash Regex

Вы можете найти каждый файл для обработки с помощью find и передать каждое имя файла в сценарий, специально созданный для поиска совпадения и печати имени файла в случае совпадения; Я бы предложил использовать сценарий, а не однострочник, чтобы облегчить обработку многострочной строки по сравнению с подсказкой.

То есть:

find . -name "*.[ch]" -exec /path/to/script {} \;

Где сценарий - это сценарий Perl:

#! /usr/bin/perl

$/ = ""; # sets the input record separator to an empty string
$_ = <>; # stores the content of the file specified in the first argument in $_

$string = <<EOF; # The multi-line string to match starts here
My
multiline
string
EOF
# The multi-line string to match ends here

/\Q$string\E/ && print($ARGV."\n"); # If $_ matches $string, prints the name of the file
  • $ / = ""; : устанавливает разделитель входных записей Perl на пустую строку; это приводит к тому, что Perl сразу читает весь файл, указанный в первом аргументе сценария;
  • $ _ = <>; : сохраняет содержимое файла, указанного в первом аргументе в $ _ ;
  • $ string = << EOF; [...] EOF : сохраняет содержимое [...] в $ string (замените [...] на соответствующую многострочную строку);
  • / \ Q $ string \ E / && print ($ ARGV. "\ n"); : if $ _ соответствует $ string , печатает имя файла.

Это пример вывода тестовой иерархии каталогов, созданный специально:

% for f in *; do printf '%s:\n\n' "$f"; <<<'' cat "$f" -; done
file1:

My
multiline
string

file2:

My
multiline
string

file3:

My
other
multiline
string

script.pl:

#! /usr/bin/perl

$/ = "";
$_ = <>;

$string = <<EOF;
My
multiline
string
EOF

$string = quotemeta($string);

/$string/&&print($ARGV."\n");

% find . -type f -exec ./script.pl {} \;                      
./file2
./file1
1
19.12.2018, 17:11
1 ответ

regex2=$'\x28'точно эквивалентен regex2='(', оболочка обрабатывает кавычки $'...', когда происходит присваивание. И (сам по себе является недопустимым регулярным выражением, поэтому [[ =~ ]]сообщает об ошибке, возвращая статус выхода2:

$ re='('; [[ "(" =~ $re ]]; echo "$?"
2

(Конечно, внутри инструкции ifвы не можете отличить код выхода 1для "нет совпадения" и 2для "ошибки", но она есть.)

Вам нужно избежать открывающей скобки из регулярного выражения:

$ re='\('; [[ "(" =~ $re ]] && echo match
match

или поместите его в группу квадратных скобок:

$ re='[(]'; [[ "(" =~ $re ]] && echo match
match

При быстром тестировании регулярные выражения Bash не поддерживают экранирование шестнадцатеричных или восьмеричных символов, поэтому re='\050'или re='\x28'не работают.

6
27.01.2020, 23:15

Теги

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