tail
他の標準ツールと組み合わせて使用グループ化コマンドいくつかの強力な建物を建てることができます。たとえば、ファイルの最初の行と最後の行を取得するには、次のようにします。
$ seq 10 > file
$ { head -n1; tail -n1; } <file
1
10
パイプからグループコマンドでファイルの内容を入力すると、tail
パイプは次のようになるため、出力を生成できません。連合国 -探す有能な:
$ seq 10 | { head -n1; tail -n1; }
1
コンテンツが十分に大きい場合は、tail
次のように動作します。
$ seq 10000 | { head -n1; tail -n1; }
1
10000
lseek
最初の失敗後はtail
失敗ではないことを知っているからだ。検索可能これはファイル記述子であり、パイプの内容をまだ読み取っていないので、最後まで内容を読み始めます。
ユーザーの観点からは、入力サイズに関係なく動作が一貫したいと考えています。 POSIXのドキュメントを見ましたが、tail
説明lseek
が見つかりませんでした。
この動作はPOSIXで指定しますか?そうでなければ、どのように結果を一貫して作成できますか?
私はGNUテールとFreeBSDテールでテストしましたが、どちらも同じ動作をしています。
ベストアンサー1
問題はここにはありませんが、tail
ここでhead
は出力したい最初の行よりもパイプからより多くの内容を読み込みます(したがって読む内容はありませんtail
)。
はい、POSIXと互換性があります。
head
入力を取得できる場合は、カーソルは出力の最後の行の直後にstdinに残る必要がありますが、そうでない場合はそうではありません。
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap01.html:
標準ユーティリティが検索可能な入力ファイルを読み取り、ファイルの終わりに到達する前にエラーなしで終了する場合、ユーティリティは、開かれたファイル記述のファイルオフセットがユーティリティが処理した最後のバイトの後に正しく配置されていることを確認する必要があります。検索できないファイルの場合、ファイルの開かれたファイル記述のファイルオフセット状態は指定されません。
head
検索できないファイルでこれを実行できることは、一度に1バイトを読む必要があることを意味するため、非常に非効率的です。これは、ユーティリティまたはGNUがread
このオプションを使用して実行する操作です。line
sed
-u
したがって、この動作が必要な場合に置き換えるhead -n 20
ことができます。gsed -u 20q
ここでは、次のようになります。
sed -e 1b -e '$b' -e d
代わりに。ここでは1つのツール呼び出ししかないため、2つのツール呼び出し間で内部バッファを共有できないという問題はありません。ただし、大容量ファイルの場合はsed
ファイル全体を読み取る方が効率が悪く、検索可能なファイルの場合はtail
ほとんどのファイルをスキップします。救うファイルの末尾に近い。
バッファリングに関する関連議論を参照してください。シェルループを使用してテキストを処理するのはなぜ悪い習慣と見なされますか?。
tail
ストリームの尾は標準入力として出力する必要があります。最適化された検索可能なファイルとして、実装はファイルの終わりに移動してそこから末尾のデータを取得できますが、呼び出し時に最初の場所の前のポイントに戻ることはできませんtail
(Busyboxはtail
以前このバグを持っています)。
たとえば、
{ cat; tail -n 1; } < file
tail
最後の行に戻ることはできますが、そうではfile
ありません。標準入力は、cat
ファイルの末尾にカーソルがある空のストリームです。ファイルをさらに詳しく見ると、このストリームからデータを回復できません。
(上記のテキストは確認のために行を描きました。公開グループの説明複数の実装が正しく行われていないことを考慮してください。)
1ソケット(探索できないファイル)の組み込みhead
機能(ksh93
前に置くと有効)/opt/ast/bin
$PATH
現れるrecvfrom(..., MSG_PEEK)
実際の入力前(使用)読むあまり読まないようにするには、どれくらい読むべきかを確認してください。他のファイル形式の場合は、一度に1バイトずつ読み取ることで置き換えられます。これはやや効率的です。これがsocketpair()
Pipes を実装するのではなく s を使う主な理由だと思いますpipe()
。他のプロセスがソケット間でデータを読み取ると、競合状態が発生する可能性があるため、これは完全に安全ではありません。現れるそして読む。