Алфавитный список Grep, если он не находится в трубопроводе

Я хочу создать псевдоним bash для grep, который добавит номера строк:

alias grep='grep -n' 

Но это, конечно же, добавляет номера строк в трубопроводы. Большую часть времени (и никаких исключений не приходит на ум) я не хочу, чтобы номера строк в конвейере (по крайней мере, внутри, возможно, ОК, если это последнее), и я действительно не хочу добавлять sed / awk / cut для трубопровод только для того, чтобы вытащить их.

Возможно, мои требования могут быть упрощены, чтобы «только добавить номера строк, если grep является единственной командой в строке». Есть ли способ сделать это без особо уродливого псевдонима?

  • Ведение журнала вывода strontr crontab в файл
  • После использования команды bg можно перенаправить вывод, например nohup?
  • Почему cat x >> x loop?
  • Значение `cat / dev / null> file`
  • Захват данных с Fluke 1620a через netcat
  • разрешение отклонено при перенаправлении вывода sudo sed
  • Выход трубопровода sed / grep не работает
  • Как я могу передать только stderr в zsh?
  • 2 Solutions collect form web for “Алфавитный список Grep, если он не находится в трубопроводе”

    Вы можете использовать функцию в bash (или любой оболочке POSIX) следующим образом:

     grep() { if [ -t 1 ] && [ -t 0 ]; then command grep -n "$@" else command grep "$@" fi } 

    Часть [ -t 1 ] использует [ команду (также известную как test ), чтобы проверить, связано ли stdout с tty.

    [ -t 0 ] проверяет стандартный ввод, так как вы указали только добавить номера строк, если grep является единственной командой в конвейере.

    (для полноты)

    Хотя ответ @ enzotib, скорее всего, вы хотите, это не то, о чем вы просили. [ -t 1 ] проверяет, является ли дескриптор файла терминальным устройством, а не что-то другое, кроме как канал (например, обычный файл, сокет, другой тип устройства, например /dev/null …)

    [ Команда не имеет эквивалента -t но для труб. Чтобы получить тип файла, связанного с файловым дескриптором, вам необходимо выполнить системный вызов fstat() . Для этого нет стандартной команды, но некоторые системы или оболочки имеют некоторые.

    С GNU stat :

     grep() { if { [ "$(LC_ALL=C stat -c %F - <&3)" = fifo ]; } 3>&1 || [ "$(LC_ALL=C stat -c %F -)" = fifo ]; then command grep "$@" else command grep -n "$@" fi } 

    Или с zsh и его собственным stat builtin (который предшествует GNU один на несколько лет), здесь загружается только как zstat :

     grep() { zmodload -F zsh/stat b:zstat local stdin_type stdout_type if zstat -A stdin_type -s -f 0 +mode && zstat -A stdout_type -s -f 1 +mode && [[ $stdin_type = p* || $stdout_type = p* ]] then command grep "$@" else command grep -n "$@" fi } 

    Теперь несколько примечаний:

    Это не только оболочки, которые используют трубы.

     var=$(grep foo bar) 

    или:

     cmd <(grep foo bar) 

    или:

     coproc grep foo bar 

    также запускайте grep с его stdout, идущим к трубе.

    Если ваша оболочка ksh93 , обратите внимание, что в некоторых системах она использует сокеты вместо труб в своих конвейерах.

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