行番号を追加するために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 ]
セクションでは[
コマンドを使用します。(また〜として知られているtest
)stdoutが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
一部のシステムではパイプのパイプの代わりにソケットペアを使用することに注意してください。