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

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

alias grep='grep -n' 

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

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

  • Копирование или перенаправление текста в качестве входа в UART, необходимо обеспечить более медленную пропускную способность
  • Как работает встроенная структура управления / перенаправления Bash
  • Открытие более 10 дескрипторов файлов с помощью ksh
  • Есть ли способ перенаправить файл, который написан
  • Создайте временный файл из перенаправления или вывода stdout
  • В форме `exec FD>` exec
  • Для перенаправления ввода существуют функциональные различия между bash / zsh <<< «$ (<файл)» и традиционным <file?
  • Маркировка команды в качестве переменной для повторного использования внутри каналов или отдельных команд
  • 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 - лучшая ОС в мире.