私は巨大なファイル(数ギガバイトなど)を持っていて、さまざまなツール(分割など)を試しましたが、必要に応じてこれをawkで実行する必要があります。
基本的にawkの機能をエミュレートしたいと思いますsplit -b 1 file
(提供されたマニュアルページとコマンドで判断するとファイルをバイトごとに1バイトに分割します)。
また、生成されたファイルのファイル名(増分)がスクリプトの実行中にstdoutに印刷され、主に他のスクリプトなどで変数として使用できるようにしたいです。
編集:これまで私がしたことは次のとおりです。
awk '{for(i=1;i<=length;i++) print substr($0, i, 1)}' filename
ファイル名の詳細
他のファイルを上書きしたくない場合は、ファイル名を増やす必要があります。 (数字または英数字)。
比較のために、split
coreutilsのツールは次のように文字を使用してファイル名を生成します。xa xb...xaa
私は次のいずれかが欲しい。または、可能であれば数字のみが必要です:1 2..444
または/および英数字ファイル名:a1 a2
答え1
GNUを使用すると、awk
次のことができます。
LC_ALL=C gawk -v RS='.{1}' '
{
file = "filename" ++n
print file
printf "%s", RT > file
close(file)
}' < input
ただし、ほとんどのファイルシステムでバイトごとに1つのファイルを作成することを考慮すると、ディスク容量(ほとんどのファイルシステムでは1バイトのファイルがまだ数KBのディスク容量を占めるため)やinodeがすぐに不足する可能性があります。そうしないと、パフォーマンスが非常に悪くなる可能性があります。数十万バイトの入力
LC_ALL=C
.
文字の代わりにバイトを一致させるために使用されます。RS='.{1}'
レコード区切り文字を1
単一文字(で囲まれた単一バイトLC_ALL=C
)に設定します。RS=.
レコード区切り文字はドット文字であるため、機能しません。正規表現と見なすにはRS
複数の文字が必要です。また動作しますが、テストの結果、3つのうち、これが最も効果的であることがわかりました。gawk
(.)
.|.
.{1}
RT
一致するテキストが含まれていますRS
。
RS
正規表現としてバイナリデータを処理でき、RT
非標準拡張です。RT
AFAIK GNU専用です。
答え2
1バイトファイルを作成するときに実行される操作は、split
ファイルに順番に番号を付けるだけですが、最大256個の異なるファイルのみを生成できます。これ以上可能なファイルの内容はなく、256個しかありません。
また、複数のGBファイルを同じ数の1バイトファイルに変換すると、処理するデータサイズが大幅に増加するため(ext4ファイルシステムでは4000以上)、各ファイルへのアクセスも遅くなります。
しかし、あなたが言ったように、データに対してさらなる処理を実行する別のオプションがあります。
また、生成されたファイルのファイル名(増分)がスクリプトの実行中にstdoutに印刷され、主に他のスクリプトなどで変数として使用できるようにしたいです。
したがって、より速いソリューションは、リソース(ディスクスペース、処理能力、時間、およびエネルギー)の消費を大幅に削減します。
0x00
からの各バイトで構成される256個のファイルを作成します0xff
。これにはすべての可能な入力が含まれます。a number
stdout+で作成されますa file name
。この数字は入力ファイルの開始位置です。ファイル名は上記で作成された256ファイルのうちの1つで、入力内のバイト値を提供します。
256個のファイルを事前生成できます(bash):
for((i=0;i<=255;i++)); do
file=prefix$(printf '%03d' "$i");
printf '%b' "$(printf '\\x%x' "$i")" >$file;
done
または、複数のGBファイルを扱うときに必要なファイルを作成してください。
LC_ALL=C gawk '
BEGIN{ #
RS=".{1}" # set the record separator
for(i=0;i<256;i++){
ord[ sprintf("%c",i) ] = i # help array ord
}
}
{
position = ++n # keep count of bytes read
file = "prefix" ord[RT] # find the file name to use
if ( ! seen[file] ) { # Have we seen this file ?
printf "%s", RT > file # If not, create it.
close(file) # close the file
seen[file]=1 # record that we have seen it.
}
print position, file # print information for next script
}
' ./input # file to process.
つまり、より速い解決策です。