Зібрати псевдоніми - номери рядків, якщо вони не знаходяться в конвеєрі


25

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

alias grep='grep -n'

Але це, звичайно, додає номери ліній до трубопроводів. Більшу частину часу (і жодні винятки не приходять до уваги) я не хочу номери ліній в трубопроводі (принаймні внутрішньо, можливо, добре, якщо він останній), і я не хочу додати sed / awk / cut трубопровід просто для того, щоб вивезти їх.

Можливо, мої вимоги можуть бути спрощені, щоб "додавати лише номери рядків, якщо grep - єдина команда в рядку". Чи можна це зробити без особливо потворного псевдоніма?

Відповіді:


27

Ви можете використовувати функцію в bash (або будь-якій оболонці POSIX) на зразок цієї:

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

[ -t 1 ]Частина використовує [команду (також відомий як test) , щоб перевірити , якщо стандартний висновок пов'язаний з терміналом.

Також [ -t 0 ]перевіряється стандартне введення, оскільки ви вказали додавати номери рядків лише, якщо grepце єдина команда в конвеєрі.


5
І зробіть тест, [[ -t 0 && -t 1 ]]якщо ви хочете лише номери рядків, якщо до терміналу підключені і стандартний вхід, і стандартний вихід.
Жил "ТАК - перестань бути злим"

3

(для повноти)

Хоча відповідь @ 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вбудованим модулем (який передує одному з кількох років 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з її виступом, що йде до труби.

Якщо ваша оболонка є ksh93, зверніть увагу, що в деяких системах вона використовує socketpairs замість труб у своїх трубопроводах.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.