Труба к моему собственному сценарию

Я недавно заметил это сообщение от grep

"grep: warning: GREP_OPTIONS is deprecated; please use an alias or script" 

Я получаю это предупреждение, потому что –color = всегда определено в моем файле .bashrc. Альянс AFAIK нецелесообразен, потому что я хочу, чтобы это работало на трубе. Например,

 echo "abc" |grep b 

следует выделить b. Поскольку псевдоним не будет работать, другим вариантом является создание сценария. Но как заставить скрипт принимать входные данные из канала? В этом случае я хочу, чтобы скрипт добавлял –color = always.

РЕДАКТИРОВАТЬ: Псевдоним работает все-таки … и так делает скрипт. Я понятия не имею, что я делаю неправильно с методом псевдонима. Однако при создании сценария обязательно укажите $ 1 для входного параметра.

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

сначала сделайте скрипт в месте пути, чтобы его исполняемый файл, например

 # ~/.bin/testgrep grep --color=always $1 

Теперь сделайте исполняемый файл сценария, например

 chmod +x ~/.bin/testgrep 

Теперь это должно сработать!

2 Solutions collect form web for “Труба к моему собственному сценарию”

grep (т. е. /bin/grep ) будет считываться со стандартного ввода, если он вызывается без аргументов имени файла. Так что просто написать скрипт, который запускает grep со входом со стандартного ввода – просто вызовите grep без аргументов имени файла. Но grep должен быть предоставлен (по крайней мере) один аргумент PATTERN (или эквивалент). Крайне негибкий способ сделать это, что вряд ли будет очень полезным в реальной жизни, состоит в том, чтобы жестко закодировать строку поиска (шаблон) в ваш скрипт grep; например,

 #!/bin/sh grep --color=always cat 

которые могут быть использованы в контексте

 ps | mygrep 

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

 #!/bin/sh grep --color=always $USER 

которые могут быть использованы в контексте

 ps -ef | mygrep 

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

 #!/bin/sh grep --color=always $1 

которые могут быть использованы в контексте

 dmesg | mygrep TCP 

и на самом деле может быть довольно полезным.

Ну, может быть, я должен сказать несколько полезный. Это довольно быстро ломается, так как вам может потребоваться несколько аргументов для указания параметров поиска:

  mygrep -i tcp Нечувствительный к регистру поиск;  найти tcp , TCP , Tcp и т. д.
 mygrep -v bash Найдите все, кроме bash .
 mygrep -e cat -e dog Найдите каждую строку, содержащую кошку или собаку .
 mygrep -f wordlist Строки поиска находятся в файле. 

Таким образом, второй проект нашего скрипта может быть:

 #!/bin/sh grep --color=always $1 $2 $3 $4 $5 $6 $7 $8 $9 

который может обрабатывать любой из приведенных выше примеров. В качестве дополнительного бонуса это не нужно использовать для чтения стандартного ввода; мы можем сказать

 mygrep -i path .bashrc 

и он будет работать

 grep --color=always -i path .bashrc 

Но мы еще не закончили! Рассматривать

 mygrep "cat food" "shopping list.txt" 

который будет работать

 grep --color=always cat food shopping list.txt 

который (попытается) найти cat в трех файлах: food , shopping и list.txt . Хорошо, мы можем справиться с этим, сказав

 #!/bin/sh grep --color=always "$1" "$2" 

но

 #!/bin/sh grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" 

не является хорошим ответом; он превратится

 mygrep "cat food" "shopping list.txt" 

в

 grep --color=always "cat food" "shopping list.txt" "" "" "" "" "" "" "" 

который будет делать то, что вы хотите, но также выпустит семь сообщений об ошибках.

Итак, что делать, что делать? Подожди; У меня есть кувалда в моем шкафуте:

 #!/bin/sh if [ "$1" = "" ] then printf "%s\n" "error: mygrep must be run with at least one argument." elif [ "$2" = "" ] then grep --color=always "$1" elif [ "$3" = "" ] then grep --color=always "$1" "$2" elif [ "$4" = "" ] then grep --color=always "$1" "$2" "$3" elif [ "$5" = "" ] then grep --color=always "$1" "$2" "$3" "$4" elif [ "$6" = "" ] then grep --color=always "$1" "$2" "$3" "$4" "$5" elif [ "$7" = "" ] then grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" elif [ "$8" = "" ] then grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" "$7" elif [ "$9" = "" ] then grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" else grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" fi 

Правильно.

  1. Это смехотворно непрактично.
  2. Даже это не удается

     mygrep -e cat -e dog -e fish file1 file2 file3 file4 

    потому что он содержит более девяти аргументов! И, хотя эта ситуация может показаться маловероятной, та же проблема возникает

     mygrep bird * 

    если в текущем каталоге содержится более восьми (не скрытых) файлов.

Итак, что делать, что делать?

TL; DR

Если вы посмотрите в bash (1) в разделе « Специальные параметры» , вы увидите, что $@ расширяется до списка позиционных параметров, начиная с одного. Когда расширение происходит в двойных кавычках, каждый параметр расширяется до отдельного слова. То есть, "$@" эквивалентно "$1" "$2" … (как реализовано в длинном скрипте выше, но не ограничиваясь первыми девятью). Итак, способ написать сценарий для обертывания (т. Е. Действовать как интерфейс для) для некоторой команды, действующей как псевдоним, является

 #!/bin/sh grep --color=always "$@" 

Псевдоним будет работать. У меня grep aliased grep --color=auto :

 % which grep grep: aliased to grep --color=auto 

И у трубопровода для grep есть поведение, которое вы желаете:

введите описание изображения здесь

  • Замена номера одним и тем же значением (числом) одного символа
  • Замена нескольких строк в sed или awk
  • Проблемы безопасности
  • Как скрипт Bash может сказать, как он был запущен?
  • Использование уведомления-отправки с помощью cron
  • Я хочу разделить сумму чисел на значение
  • как заставить Expect ждать завершения другого скрипта
  • Условие скрипта Bash всегда передается, даже когда grep не должен возвращать ничего
  • Универсальный Node.js shebang?
  • Как я могу определить, есть ли я в текстовой области?
  • ksh не может cp из местоположения с пространством в нем?
  • Linux и Unix - лучшая ОС в мире.