小さなファイルに対していくつかのバグ修正を実行するには、長いテキストファイルの最初の行を取得する必要があります(Pythonスクリプトは予想どおり大きなテキストファイルを消化しません)。ただし、バグ修正を意味するには、行が基本的にバイト単位で完全なコピーである必要があり、文字エンコード、行末文字、見えない文字、または見えない文字に関連する潜在的な問題を特定する必要があります。存在しません。次の簡単なソリューションでこれを達成できますか?それとも私が使用している出力に何かがありませんかhead
?
head infile.txt > output.txt
現在head
、またはelseを使用したバイナリコピーに関するより一般的な質問が投稿されました。dd
ここ。
答え1
POSIX は入力を意味します。head
はテキストファイルと定義テキストファイル:
3.397 テキストファイル
ゼロ行以上の文字を含むファイル。この行にはNUL文字は含まれておらず、
{LINE_MAX}
この文字を含むどの行もバイトより長くすることはできません<newline>
。 POSIX.1-2008はテキストファイルとバイナリファイルを区別しませんが(ISO C標準を参照)、多くのユーティリティはテキストファイルを操作するときに予測可能または意味のある出力のみを生成します。これらの制限を持つ標準ユーティリティは、常にSTDINまたはINPUT FILESセクションに「テキストファイル」を指定します。
その結果、情報が失われる可能性があります。
答え2
明らかにhead
テキストファイルではない場合、入力は歪みます。
$ wc /bin/ls
431 3454 126496 /bin/ls
$ head -n 431 /bin/ls > a
wc a
431 3447 125378 a
$ diff a /bin/ls
Binary files a and /bin/ls differ
$ md5sum /bin/ls a
42846aa64774a99f0f1feba36ec2e099 /bin/ls
de032f5aa5ef356fb7d5ab4dc622df2e a
$ wc -c /bin/ls a
126496 /bin/ls
125378 a
Stéphane Chazelasはコメントで良い指摘をしました。
wc -l
改行回数を報告します。/bin/ls
最後の発生以降、より多くのバイトがある可能性があり、0xa
これはhead -n 431
出力されません。 (あなたが使用しているように見える)GNUツールは通常、バイナリデータ(NULバイトと任意の長い行)を処理できます。
したがって、使用時に出力エラーが発生するのは、head -n
最後の文字の後に追加のデータがあるためです\n
。 GNUソースコードを見ると、行head
読み取り機能とバイト読み取り機能の両方が同じsafe_open()
呼び出しを使用するため、実際に返すことができるものとの間に違いがないことを確認できます。これは、GNUの実装head
(Linuxを使用するほとんどの非組み込みオペレーティングシステムで一般的に見られる)を使用することが非常に安全であることを示しています。
man head
しかし、行の代わりにバイトで動作するように指示すると正しく動作するようです。
-c, --bytes=[-]NUM
print the first NUM bytes of each file; with the leading '-',
print all but the last NUM bytes of each file
この-c
オプションを使用すると、同じファイルが生成されたように見えます。
$ wc -c /bin/ls
126496 /bin/ls
$ head -c 126496 /bin/ls > a
$
$ md5sum /bin/ls a
42846aa64774a99f0f1feba36ec2e099 /bin/ls
42846aa64774a99f0f1feba36ec2e099 a
これにより、次のような結果も得られますdd
。
$ dd if=/bin/ls of=a bs=126496 count=1
1+0 records in
1+0 records out
126496 bytes (126 kB, 124 KiB) copied, 0.000469919 s, 269 MB/s
$ diff a /bin/ls
$
このフラグを使用すると、常に正しいバイナリ出力が生成されることを指定する公式文書を指すことはできませんが、-c
合理的な仮定のようです。
答え3
あなたはそれを使用することができますsplit(1)
。これにより、各ファイルがバイト単位で正確なファイルフラグメントに対応する多くのファイルが生成されます。
例: FILE=test ; split -b 1000 $FILE $FILE.split.
1000 バイトのファイル test.split.aa や test.split.ab などが生成され、cat $FILE.split.* > $FILE.recompose
$FILE.recompose は元の $FILE と同じように生成されます。ファイルが1000 * 26 * 26より大きい場合は、サフィックスの長さを増やす必要があります(参照man split
)。
これを使用すると、split -l 100
各ファイルに100行が配置されます。私はこれがバイトで正しいと確信しています。