Grepエイリアス - 行番号(パイプラインにない場合)

Grepエイリアス - 行番号(パイプラインにない場合)

行番号を追加するためにgrepのbashエイリアスを作成したいと思います。

alias grep='grep -n'

もちろん、これによりパイプラインのライン数も増えます。ほとんどの場合(例外なし)、パイプ内に行番号があることを望まない(少なくとも内部的には最後の行であれば問題ありません)、sed / awk / cutパイプを追加したくありません。取り出してください。

たぶん私の要件は、「grepが行の唯一のコマンドである場合にのみ行番号を追加する」ように単純化できます。特に見苦しいニックネームを要求せずにこれを行う方法はありますか?

答え1

bash(またはすべてのPOSIXシェル)では、次のように関数を使用できます。

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

この[ -t 1 ]セクションでは[コマンドを使用します。(また〜として知られているteststdoutがttyに関連付けられていることを確認してください。

また、次の場合は[ -t 0 ]行番号のみを追加するように指定したので、標準入力も確認してください。grepただパイプラインのコマンド。

答え2

(完全さのために)

しかし、@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一部のシステムではパイプのパイプの代わりにソケットペアを使用することに注意してください。

関連情報