Что случилось с этим grep?

> output2.txt cd # some directory i'm trying to search find views/shared -type f -name "*.js" -print0 | while IFS= read -r -d $'\0' line; do echo -n "${line%.js}" | tee -a ~/Documents/counter/output2.txt grep -lr "${line%.js}" . | wc -l | tee -a ~/Documents/counter/output2.txt # produce a count of occurrences regex='[a-zA-Z]+.extend' grep -f $line $regex grep -lr "${line%.js}" . | tee -a ~/Documents/counter/output2.txt # produce a list of occurrences done 

Возвращает

 grep: brackets ([ ]) not balanced 

Все примеры, которые я видел в Интернете, похоже, указывают на то, что здесь нет ничего плохого, поэтому я довольно смущен

Конечно, квадратные скобки сбалансированы, не так ли?

  • Закрыть / убить / скрыть одно окно терминала в bash on 'process complete'
  • Rm без удаления самого файла / каталога
  • Не удалось удалить Root CA (UNIX: операция не разрешена)
  • Создание файла DMG на Gentoo
  • Поиск источника и источника копирования для плоской цели
  • Как узнать, какие порты прослушиваются определенным PID?
  • Я изменил свой PATH при установке git. Каков путь по умолчанию на Mac?
  • OSX: генерировать контрольную сумму MD5 рекурсивно в текстовом файле, содержащем файлы с соответствующей контрольной суммой
  • 2 Solutions collect form web for “Что случилось с этим grep?”

    Ваша проблема – опция -f . Вместо указания файла для поиска, -f указывает файл для чтения списка шаблонов. Справочная страница OS X grep объясняет это, хотя и не очень четко :

      -f file, --file=file Read one or more newline separated patterns from file. Empty pattern lines match every input line. Newlines are not considered part of a pattern. If file is empty, nothing is matched. 

    Справка для GNU grep на самом деле более проста:

     $ grep --help | grep -- '-f,' -f, --file=FILE obtain PATTERN from FILE $ 

    Такое поведение -f , согласно man-странице GNU grep, specified by POSIX.

    Возможно, ваше исправление изменит вашу строку:

     grep -f $line $regex 

    чтобы:

     egrep "$regex" -- "$line" 
    • Вы используете расширенное регулярное выражение, поэтому используйте egrep или grep -E
    • Параметр -- предотвратит разбор grep от любых параметров в переменной $line , например, он защитит вас от файла с именем « -r funnyname.js »,

    Если вход, поступающий в трубу grep, содержит квадратные скобки ('[' и ']'), grep будет с трудом обрабатывать их изящно. Сначала вы должны «дезинфицировать» вход, используя что-то вроде этого, чтобы заключить каждую квадратную скобку в пару квадратных скобок, тем самым заставляя их интерпретироваться как буквенные символы, которые нужно сопоставить:

     CommandYouWantToPipeThroughGREP | sed -e 's^\([][]\)^\[\1\]^g' | grep ... 

    Объяснение команды sed:

    sed -e : выражение следует за -e. Он должен быть заключен в одиночные или двойные кавычки.

    s^ : [s] earch for. «^» используется как разделитель полей. Каждый раз, когда вы видите «^», он ограничивает новую часть параметра поиска.

    \(\) и \1 : экранированные скобки заключают в себе шаблон, который вы хотите получить как переменную в sed. Первый такой шаблон называется «\ 1»; второй – «\ 2» и т. д.

    [][] : Внешние две скобки заключают в себе внутренние два. Первый символ после «[» автоматически считается буквенным (экранированный / не имеющий особого значения). Поскольку этот первый символ является скобкой, следующая скобка также считается буквой, если только она не является единственной скобкой до конца этого поля с символом «^». (По крайней мере, это мое понимание того, как это работает …)

    \[\1\] : Закрепить переменную sed 1 ("\ 1") в литеральных скобках и отправить ее на вывод.

    g : [g] reedy. Это означает: «Найти и заменить все примеры текста поиска, а не только первого».

    Итак, просто подключите любой вход, который может содержать квадратные скобки через эту команду sed, прежде чем конвейер через grep, и grep будет искать скобки буквально, вместо того, чтобы интерпретировать их как специальные символы. К сожалению, казалось бы, если вы подключаетесь к команде ANOTHER grep, после первого, вам нужно запустить ее через sed, чтобы снова избежать скобок.

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