Grep alias - bir boru hattında değilse satır numaraları


25

Grep için satır numaraları ekleyen bir bash takma adı oluşturmak istiyorum:

alias grep='grep -n'

Ancak bu, elbette, boru hatlarına da satır numaraları ekliyor. Çoğu zaman (ve hiçbir istisna aklıma gelmiyor) Bir boru hattı içindeki satır numaralarını istemiyorum (en azından dahili olarak, en son eğer muhtemelen tamamdır) ve gerçekten bir sed / awk / cut eklemek istemiyorum boru hattı sadece onları çıkarmak için.

Belki de benim gereksinimlerim basitçe "satırdaki tek komut grep ise, sadece satır numaraları eklemek" ile basitleştirilebilirdi. Bunu özellikle çirkin bir takma ad olmadan yapmanın bir yolu var mı?

Yanıtlar:


27

Bash (veya herhangi bir POSIX kabuğundaki) bir işlevi aşağıdaki gibi kullanabilirsiniz:

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

[ -t 1 ]Parçası kullanan [komutu (aynı zamanda test) stdout'u uçbirimlerden ile ilişkili olup olmadığını kontrol etmek için.

Ayrıca , boru hattındaki tek komut [ -t 0 ]buysa grep, sadece satır numaraları eklemek için belirttiğinizden, standart girişi de kontrol eder .


5
Ve [[ -t 0 && -t 1 ]]eğer sadece standart giriş ve standart çıkış bir terminale bağlıysa hat numaralarını istiyorsanız testi yapın .
Gilles 'SO- kötülük' dur '

3

(Tamamlamak için)

İken @ enzotib cevabı büyük olasılıkla istediğini, bu sen istedin değil. [ -t 1 ]Dosya tanımlayıcısının bir uçbirim aygıtı olup olmadığını denetler, borudan başka bir şey olmadığını (normal bir dosya, bir soket, /dev/null... gibi başka bir aygıt türü ...)

[Komutu muadili yoktur -tama borular içindir. Bir dosya tanıtıcısına bağlı dosyanın türünü almak için, fstat()sistem çağrısı üzerinde yapmanız gerekir . Bunu yapmak için standart bir komut yoktur, ancak bazı sistemler veya mermilerde bazıları vardır.

GNU ile 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
}

Ya da zshve kendi statyerleşikleri ile (GNU'yu birkaç yıl önce öldüren), buraya zstatsadece yüklendi :

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
}

Şimdi birkaç not:

Sadece boru kullanan kabuk boru hatları değil .

var=$(grep foo bar)

veya:

cmd <(grep foo bar)

veya:

coproc grep foo bar

ayrıca grepstdout bir boruya gidiyor.

Kabuğunuz varsa ksh93, bazı sistemlerde, boru hatlarındaki borular yerine soket çiftleri kullandığına dikkat edin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.