ファイルがPOSIXで定義されたテキストファイルであるためには、どのような条件を満たす必要がありますか?


22

POSIXは、テキストファイルを次のように定義します。

0個以上の行に編成された文字を含むファイル。行にはNUL文字が含まれておらず、<newline>文字を含めて、長さが{LINE_MAX}バイトを超えることはできません。POSIX.1-2017はテキストファイルとバイナリファイルを区別しませんが(ISO C標準を参照)、多くのユーティリティは、テキストファイルを操作する場合にのみ予測可能または意味のある出力を生成します。このような制限がある標準ユーティリティは、STDINまたはINPUT FILESセクションで常に「テキストファイル」を指定します。

ソース:http : //pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_403

ただし、いくつか不明確なことがあります。

  1. テキストファイルは通常のファイルである必要がありますか?上記の抜粋では、ファイルが通常のファイルでなければならないことを明示的に示していません

  2. 1つの文字と1つの文字のみ(つまり、改行で終わらない単一の文字)が含まれている場合、ファイルをテキストファイルと見なすことはできますか?この質問はきちんと聞こえるかもしれませんが、「1つ以上の文字」ではなく「文字」という言葉を使用しています。他の人は同意しないかもしれませんが、「1つ以上の文字」を意味する場合は、明示的に言う必要があると思います

  3. 上記の抜粋では、「行」を参照しています。名前に「空の行」、「表示行」、「不完全な行」、「行」という名前の行がある4つの定義が見つかりました。「空」、「表示」、「不完全」が省略されているため、「行」を意味すると推測するのか、またはこれらの定義の4つすべてが上記の抜粋の行と見なされているのですか?

このテキストブロックの後に来るすべての質問は、「文字」が「1つ以上の文字」を意味するという推論に依存しています。

  1. ファイルが空の場合、1つ以上の文字が含まれていないため、テキストファイルではないと推測できますか?

このテキストブロックの後に来るすべての質問は、上記の抜粋では、行が「行」として定義され、名前に「行」を含む他の3つの定義は除外されるべきであるという推論に依存します:

  1. 「ゼロ行以上」の「ゼロ」は、改行で終わらない1つ以上の文字が含まれているファイルがテキストファイルと見なされることを意味しますか?

  2. 「ゼロ以上の行」とは、1つの「行」(0以上の文字と終了する改行)が登場すると、最後の行が「不完全な行」(1つ以上の非行ファイルの最後の改行文字)?

  3. 「なし[行なし]は、改行文字を含めて{LINE_MAX}バイトを超えることはできません」とは、テキストファイル内の特定の「行」で許可される文字数に制限があることを意味しますかUbuntu 18.04およびFreeBSD 11.1のLINE_MAXは「2048」ですか?


良い質問、ハロルド!用語の素晴らしい議論になります。私は質問の余分回upvoteことがしたい
Sergiy Kolodyazhnyy

回答:


23
  1. テキストファイルは通常のファイルである必要がありますか?上記の抜粋では、ファイルが通常のファイルでなければならないことを明示的に示していません

    いいえ。抜粋では、潜在的なテキストファイルとしての標準入力も明記しています。などの他の標準ユーティリティは make特にテキストファイルとしてキャラクタースペシャルファイル /dev/null 使用ます

  2. 1つの文字と1つの文字のみ(つまり、改行で終わらない単一の文字)が含まれている場合、ファイルをテキストファイルと見なすことはできますか?

    その文字は<newline>である必要があります。そうでない場合、これはlineではないため、そのファイルはテキストファイルではありません。正確にバイト0Aを含むファイルは、単一行のテキストファイルです。空の行は有効な行です。

  3. 上記の抜粋では、「行」を参照しています。名前に「空の行」、「表示行」、「不完全な行」、「行」という名前の行がある4つの定義が見つかりました。「空」、「表示」、「不完全」が省略されているため、「線」を意味すると推測することになっていますか

    それは実際には推論ではなく、まさにそれが言っていることです。「行」という言葉には文脈的に適切な定義が与えられているので、それはそれが言っていることです。

  4. ファイルが空の場合、1つ以上の文字が含まれていないため、テキストファイルではないと推測できますか?

    空のファイルはゼロ(またはそれ以上)行で構成されているため、テキストファイルです。

  5. 「ゼロ行以上」の「ゼロ」は、改行で終わらない1つ以上の文字が含まれているファイルがテキストファイルと見なされることを意味しますか?

    いいえ、これらの文字は行に編成されていません。

  6. 「ゼロ以上の行」とは、1つの「行」(0以上の文字と終了する改行)が登場すると、最後の行が「不完全な行」(1つ以上の非行ファイルの最後の改行文字)?

    そうではありません違法それは単なるテキストファイルではありません。テキストファイルを指定する必要があるユーティリティは、代わりにそのファイルを指定した場合、逆の動作をする可能性があります。

  7. 「なし[行なし]は、改行文字を含めて{LINE_MAX}バイトを超えることはできません」とは、テキストファイル内の特定の「行」で許可される文字数に制限があることを意味しますか

    はい。

この定義は、テキストベースのユーティリティ(などgrep)が確実に受け入れるものに限界を設定しようとしているだけです。彼らは自由に物事をより自由に受け入れることもでき、実際には頻繁に受け入れます。固定サイズのバッファを使用して行を処理したり、改行がいっぱいになる前に改行を表示したりすることなどが許可されています。物事を読みすぎている可能性があります。


1
ポイント2について確かですか?標準では、「0行以上」と明示されています。そのprintf "a" > file定義に従ってテキストファイルを作成します。4への回答touch fileは、テキストファイルを作成する一方で、作成printf "a" > fileしないことを示唆しているため、2と5への回答と矛盾しているようです。
テルドン

4
@terdon:マイケルの答えに矛盾はありません。基本的に、POSIXテキストファイルは、内容が正規表現(.{0,M}\n)*(暗黙的にアンカーされ、両端)に\n一致し、改行に一致し、改行.ではない任意の文字に一致Mし、数値のプレースホルダーであるファイルであると言っているようですLINE_MAX-1 特に、これは空のファイルはゼロ行で構成される有効なテキストファイルであることを意味しますが、空でないテキストファイルは改行で終了する必要があります(そうでなければ、不完全な行が含まれ、不完全な行は行ではないため) )。
イルマリカロネン

@Michael Homer通常のファイルに関して、/ dev / null以外の例はありますか?1つ以上のヌル文字が含まれているため、実際にはテキストファイルではありません。
ハロルドフィッシャー

1
@HaroldFischer /dev/nullは空のファイルです。あなたは考えています/dev/zero
マイケルホーマー

@HaroldFischer、いや、/dev/null空のように読み込みます。読み込み中にデータを取得しません。それらの多くは本質的に動的であるため、ここで非正規のファイルを検討することが理にかなっているとは思いません。これには、パイプ、ソケット、charデバイスが含まれます。これらは基本的に、他のエンティティとの間のトランスポートインターフェイスです。静的なデータセットは保持されないため、fileのプロパティではなく、転送されたデータのプロパティを考慮する方が理にかなっています
-ilkkachu

7

POSIXで定義されているとおり:

はい、テキストファイルは(基本的に):

0個以上の行に編成された文字を含むファイル。

この定義も含めると便利です。

3.92文字列

最初のヌルバイトで終了する連続した文字のシーケンス。

3.195不完全な行

ファイルの最後にある1つ以上の非<newline>文字のシーケンス。

3.206ライン

ゼロ個以上の<newline>以外の文字と、終了する<newline>文字のシーケンス。

3.243改行文字(<改行>)

出力ストリームで、印刷が次の行の先頭から開始されることを示す文字。これは、C言語で「\ n」で指定された文字です。この文字が、次の行への移動を達成するためにシステムによって出力デバイスに送信される正確なシーケンスであるかどうかは指定されていません。

3.247 NUL

すべてのビットがゼロに設定された文字。

「テキストファイル」にはNULバイトが含まれないことに注意してください。


そう:

  1. テキストファイルは通常のファイルである必要がありますか?
    いいえ、そうである必要はありません。「テキストファイル」は、読み取られたときに何が含まれるかによって定義されます。ファイルに「ゼロ行以上」が含まれている場合、それはテキストファイルです。のような一部のファイルには/dev/stdin、一度に読み取られた場合はテキストファイルが含まれ、次回は読み取られません。
  2. 1文字と1文字のみを含む場合、ファイルをテキストファイルと見なすことができますか?
    いいえ、それは不完全な行です(3.195)。
    テキストファイルには、「不完全な行」のみが含まれます。
  3. 私はそれらが「線」を意味すると推測することになっていますか?
    はい、そうすべきです。
  4. ファイルが空の場合、テキストファイルではないことを安全に推測できますか?
    いいえ、空のファイル(ゼロ文字)は有効な「テキストファイル」です。
    上から:…ゼロ行以上…。ゼロ行(ゼロ文字)は有効な「テキストファイル」です。
  5. …改行で終わらない1つ以上の文字が含まれている場合、テキストファイルと見なされますか?
    いいえ、(技術的に)有効な「ライン」ではなく「不完全なライン」です。
  6. 「ゼロ行以上」の「ゼロ」は、改行で終わらない1つ以上の文字が含まれているファイルがテキストファイルと見なされることを意味しますか?
    いいえ、不完全な行は「行」ではありません。テキストファイルに不完全な行があってはなりません

  7. …テキストファイルの特定の「行」で許可される文字数に制限があります…?
    はい、有効な「テキストファイル」の任意の行で{LINE_MAX} バイト以下(文字ではなく)が許可されます。
    {LINE_MAX}の値は、ファイル<limits.h>で指定されます
    Cの賢明な行バッファーサイズも読み取りますか?)。

    {LINE_MAX}
    特に記載がない限り、ユーティリティがテキストファイルの処理として記述されている場合の、ユーティリティの入力行(標準入力または別のファイル)の最大長(バイト単位)。長さには、末尾のスペースが含まれます。
    最小許容値:{_POSIX2_LINE_MAX}

    GNUベースのシステムの場合、設定された制限はありません(メモリを除く)

    マクロ:int LINE_MAX
    テキスト指向のPOSIX.2ユーティリティがサポートできる最大のテキスト行。(これらのユーティリティのGNUバージョンを使用している場合、利用可能な仮想メモリによる制限を除いて実際の制限はありませんが、ライブラリがこれを通知する方法はありません。)

    posix_lim.h(少なくとも64ビットLinux GNUシステムの場合)2048に定義され ているようです:

    $ grep -ri 'POSIX2_LINE_MAX' /usr/include/ 
    
    /usr/include/x86_64-linux-gnu/bits/xopen_lim.h:#define NL_LANGMAX       _POSIX2_LINE_MAX
    /usr/include/x86_64-linux-gnu/bits/posix2_lim.h:#define _POSIX2_LINE_MAX                2048
    /usr/include/x86_64-linux-gnu/bits/posix2_lim.h:#define LINE_MAX                _POSIX2_LINE_MAX
    

    また、POSIX ユーティリティgetconfを使用して見つけることもできます

    $ getconf LINE_MAX
    2048
    

関連: テキストファイルが改行で終わる必要があるのはなぜですか?


2
この答えはほとんど正しいですが、「テキストファイルは通常のファイルでなければなりません」に対する正しい答えはnoです。どんな種類のファイルでもテキストファイルにできます。内容の問題であり、ファイルの種類は無関係です。fileユーティリティは、特殊なファイルのファイルタイプを報告し、それは、ユーティリティ工事、使用、どれだけですfile - <…か(Linuxは)file -s …特別なファイルのファイル内容にその経験則を参照してください。特殊ファイルは、開くたびに異なるコンテンツを持つことができるため、毎回テキストファイルになる場合と、テキストファイルになる場合があります。/dev/nullコンテンツは常にテキストファイルであるため、常にテキストファイルです。
ジル 'SO-悪であるのをやめる'

1
grepファイルを使用するのではなく、getconfシステムのconf値を取得するために使用できます。たとえばgetconf LINE_MAX、私のシステムでは2048(バイト)を返します(Ubuntu 16.04)。
heemayl

変数が定義されているファイルを見つけたいので、grepが必要で、仕事をしました(すぐに)。しかし、はい、getconfconfigの現在の値を読み取ることができます。
アイザック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.