同じ結果を生成する次の2つのコマンドを使用しています。
[root@localhost ~]# grep line comments
The line should start with a single quote to comment in VB scripting.
Double slashes in the beginning of the line for single line comment in C.
[root@localhost ~]#
[root@localhost ~]# grep line <comments
The line should start with a single quote to comment in VB scripting.
Double slashes in the beginning of the line for single line comment in C.
[root@localhost ~]#
これら2つの方法が互いに置き換え可能である場合の利点/欠点を説明してください。
答え1
man grep
ページから(Debianの場合):
説明する
grep searches the named input FILEs (or standard input if no files are named, or if a single hyphen-minus (-) is given as file name) for lines containing a match to the given PATTERN. By default, grep prints the matching lines.
最初のケースではgrep
ファイルが開き、2番目のケースではシェルがファイルを開き、それを標準入力に割り当て、grep
ファイルgrep
名引数が渡されない場合は標準入力をgrepする必要があるとします。
1の利点:
grep
複数のファイルをgrepできます1。grep
ファイル名が表示されるたびに表示されることがありますline
。grep
fadvise(POSIX_FADV_SEQUENTIAL)
開いているファイル記述子に対して操作を実行することは可能です2(しかし、実装についてはわかりません)。
2の利点:
ファイルを開くことができない場合、シェルはより関連性のある情報(スクリプトの行番号など)を含むエラーを返し、より一貫した方法でファイルを開きます(シェルが他のコマンドのためにファイルを開くことを許可した場合) )。 )
grep
。ファイルを開くことができない場合はgrep
呼び出しさえできません(一部のコマンドでは - ではないかもしれませんが、 -grep
大きな影響を与える可能性があります)。grep line < in > out
、開くことができない場合は作成または切り捨てられin
ませout
ん。-
珍しい名前(またはで始まるファイル名など)を持つ一部のファイルには問題はありません-
。装飾:必要に応じて、
<file
コマンドラインの任意の場所に配置して、コマンドフローをより自然に表示できます。<in grep line >out
外観:GNUを使用すると、
grep
ファイル名だけでなく、一致する行の前に使用するタグを次のように選択できます。<file grep --label='Found in file at line' -Hn line
パフォーマンスの観点からは、grep
ファイルを開くことができない場合は、リダイレクトを使用したときに実行を保存できますが、他にgrep
大きな違いはないと予想されます。
リダイレクトを使用すると、追加のパラメータをに渡す必要がなくなり、パラメータの解析がやや簡単になりgrep
ますgrep
。一方、シェルはファイルディスクリプタdup2()
をファイルディスクリプタ0に転送するために、ファイルディスクリプタに対して(少なくとも)追加のシステムコールを実行する必要があります。
(ここではGNU)ファイルの残りの部分を見ることができるように、一致する行に戻ることを望みます{ grep -m1 line; next command; } < file
(ファイルが検索可能かどうかを決定する必要があります)。つまり、stdinの位置は別の出力です。これにより、これを最適化することができ、心配することが1つ減ります。grep
grep
seek()
next command
grep
grep -m1 line file
grep
ノート
これを使用して、zsh
次のことができます。
grep line < file1 < file2
しかし、これはユーティリティをcat file1 file2 | grep line
呼び出さないcat
のと同じであるため、効率が悪くなり、最初のファイルが改行で終わらず、どのファイルにパターンが見つかったかを知らせないと混乱を招く可能性があります。
grep
²これは、I / Oスケジューラがデータを読み取る方法など、より多くの情報に基づいて決定を下すためにファイルを順番に読み取るようにシステムに指示します。grep
これができます私自身fd、しかしfd 0でこれを行うのは間違っています。借りるfdのような呼び出し元から(またはむしろファイル説明を開く参照)は、後でまたは同時に非順次読み取りに使用できます。しかし、実際にはGNUがsort
まだこれをやっていることがわかります。
ksh93
3および(およびの一部のシステム)では、リダイレクトターゲットで使用されているときに実際にファイルシステムでファイルを開くのではなく、特別な目的でシェルから傍受される類似のbash
ファイルがあります。これらのファイルはファイルシステムには存在しません。)識別された目的と同じですが、少なくともここでは名前空間がより適しています(誰でもすべてのディレクトリに名前付きファイルを作成できますが、管理者だけが名前付きファイルを作成できるため、管理者はよりよく知る必要があります)。/dev/tcp/host/port
/dev/fd/x
bash
/dev/stdin
-
grep
-
/dev/tcp/host/port
答え2
StephaneChazelasの答えはこれをカバーしており、grep(1)
ほとんどのUnix系統コマンドはこのように動作しますが、すべてではありません。標準読み取り方法は、標準入力(キーボード、リダイレクトを介したファイル、または< file
他のコマンドのパイプ出力、愚かな例ls * | grep '^ab*c$'
)、または引数として提供されたファイル(たとえば)から読み取ることですgrep comment file1 file2 file3
。一部のコマンドは、名前付きファイルが-
標準入力と呼ばれる規則を使用するため、生成されたすべてのエントリをmake-middle | cat head - tail
使用してストリームをインポートし、コマンドをより柔軟に使用できるように設計されています。head
gen-middle
tail
どちらが良いですか?動作する限り、次のcmd file
より短いcmd < file
ことがあります。非常に小さいシェルがファイルを frobbing( )<
するのと、コマンド自体がこれを行うまでの時間差はありますが、一日中別の操作をしない限り、目立たないでしょう。これは、Stephenの回答に記載されている利点などの考慮事項によって異なります。