Выделение метасимволов в основных / расширенных строках регулярных выражений posix в grep

Можно ли избежать всех метасимволов строки внутри переменной, прежде чем передавать ее в grep? Я знаю, что подобный вопрос был задан раньше на SE ( здесь ), а также хорошее объяснение здесь , но мне было просто интересно, возможно ли это с базовым / расширенным шаблоном regex posix вместо perl-шаблона? (в настоящее время я читаю синтаксис regex perl, чтобы понять его сначала, а не прыгать в решение)

Почему это требование: (Мета, не требуется для ответа)

Я пытался написать небольшой скрипт для разделения больших файлов, где я разделял файлы на file_name.ext.000 , file_name.ext.001 … и т. Д., file_name.ext.001 отлично работает. Теперь мне не нравится разделять те файлы, которые уже разделены (т. Е. Имеют имена файлов с 3-мя символьными расширениями, которые являются всеми цифрами, а их размер суммируется до исходного размера файла. Теперь, если я использую простое расширение оболочки, например file_name.ext.* он также соответствует файлам, имеющим file_name.ext.ext2 и, следовательно, общие несоответствия размера и разделение происходит, даже если нет необходимости повторно отбирать. Поэтому я бы проверял только файлы, имеющие имя file_name.ext.### where ### являются цифрами. Мое текущее выражение, чтобы найти размер файла этих частей, выглядит следующим образом:

 FILE_SIZE_EXISTING=$( (find "$DESTINATION" -type f -regextype posix-extended -regex "^$DESTINATION/$FILE_BASENAME(\.[[:digit:]]{3})?$" -print0 | xargs -0 stat --printf="%s\\n" 2>/dev/null || echo 0) | paste -sd+ | bc) 

Это работает для простых имен файлов. Однако это не работает, если какое-то причудливое имя, например, содержит [] и т. Д. Существует ли обходной путь? Я новичок в сценариях оболочки и, следовательно, не знаю perl.

One Solution collect form web for “Выделение метасимволов в основных / расширенных строках регулярных выражений posix в grep”

Как процитировать специальные символы (переносимо)

Следующий фрагмент добавляет обратную косую черту перед каждым символом, который является особым в расширенных регулярных выражениях, используя sed чтобы заменить любое появление одного из символов ][()\.^$?*+ Обратным слэшем, за которым следует этот символ:

 raw_string='test[string]\.wibble' quoted_string=$(printf %s "$raw_string" | sed 's/[][()\.^$?*+]/\\&/g') 

Это приведет к удалению конечных строк в $raw_string ; если это проблема, убедитесь, что строка не заканчивается символом новой строки, добавив инертный символ в конце, а затем удалите этот символ.

 quoted_string=$(printf %sa "$raw_string" | sed 's/[][()\.^$?*+]/\\&/g') quoted_string=${quoted_string%?} 

Как цитировать специальные символы (в bash или zsh)

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

 quoted_string=${raw_string//\\//\\\\} for c in \[ \] \( \) \. \^ \$ \? \* \+; do quoted_string=${quoted_string//"$c"/"\\$c"} done 

Как цитировать специальные символы (в ksh93)

Конструкция замены струн Ksh более мощная, чем уполированная версия в bash и zsh. Он поддерживает ссылки на группы в шаблоне.

 quoted_string=${raw_string//@([][()\.^$?*+])/\\\1} 

Что вы на самом деле хотите

Вам не нужно find здесь: шаблонов оболочки достаточно для соответствия файлам, заканчивающимся тремя цифрами. Если файл детали не существует, шаблон шара остается нерасширенным. Существует также более простой способ добавления размеров файлов: вместо использования stat (который существует во многих вариантах unix, но имеет различный синтаксис для каждого) и выполняет сложную конвейерную обработку для суммирования значений, вы можете вызвать wc -c (на обычные файлы, на большинстве систем wc будет смотреть на размер файла и не беспокоить, чтобы открыть файл и прочитать байты).

 set -- "$DESTINATION/$FILE_BASENAME".[0-9][0-9][0-9] case $1 in *\]) # The glob was left intact, so no part exists do_split …;; *) # The glob was expanded, so at least one part exists FILE_SIZE_EXISTING=$(wc -c "$@" | sed -n '$s/[^0-9]//gp') if [ "$FILE_SIZE_EXISTING" -ne "$(wc -c <"$DESTINATION/$FILE_BASENAME")" ]; then do_split … fi 

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

  • Освободить память в perl-скрипте
  • Вставить переменную в строку в случайное место?
  • Показывать только строки, которые находятся во всех текстовых файлах, по крайней мере, один раз
  • Удалить строки, начинающиеся с #
  • Окрашивание хвостового выхода с помощью perl
  • Использование kornshell или Perl для обхода разрешений, необходимых для root
  • perl rename: предварительное присвоение набора имен файлов в подкаталогах
  • Специальный символ '#' в команде Perl SSH
  • ssed -R по сравнению с perl -pe
  • запустить скрипт perl с неизвестным местоположением perl
  • Как добавить столбец в начало файла с помощью perl?
  • Interesting Posts

    Debian netinstall over wifi?

    Доступ к сетевой службе NAT для динамического открытого IP-адреса из локальной сети

    Проблема прозрачности расширения hangouts Google в Linux Mint?

    Вопрос Unix для файла формата даты

    Установка Centos-7 зависает в пакете microcode-ctl

    Последовательность инициализации завершена, но терминал не даст подсказки

    как я могу вызвать скрипт bash из сценария init.d?

    Как grep файл для отметки времени? Я ищу цифры часа

    Безопасно ли рекурсивное сжатие с помощью tar, gzip и pigz?

    Передать переменную с помощью EOF и использовать переменную хоста

    Странные символы вместо значков в Firefox

    Grep. Найти несколько шаблонов AND в любом порядке с использованием одного условия

    Идентификационные результаты различаются в зависимости от того, кто спрашивает

    Копирование ОС с одного диска на другой, переходящего из MBR в GPT, – что нужно отслеживать?

    маркировать или цвет пустые каталоги для `ls`

    Linux и Unix - лучшая ОС в мире.