web-dev-qa-db-ja.com

テキストファイルを行の長さでフィルタリングするLinuxシェルコマンド

壊れたパーティションの30GBのディスクイメージがあります(dd if=/dev/sda1 of=diskimage)いくつかのテキストファイルを復元する必要があります。 foremostのようなデータカービングツールは、ヘッダーが明確に定義されたファイルでのみ機能します。つまり、プレーンテキストファイルでは機能しないため、親友stringsに頼りました。

strings diskimage > diskstrings.txtは、実際に必要なテキストと混合された、ほとんど役に立たない文字列の束を含む3GBのテキストファイルを作成しました。

ほとんどの破片は、本当に長く、途切れのない文字化けした文字列になる傾向があります。私が関心のあるものは16kb未満であることが保証されているので、ファイルを行の長さでフィルタリングします。これが私が使用するPythonスクリプトです:

infile  = open ("infile.txt" ,"r");
outfile = open ("outfile.txt","w");
for line in infile:
    if len(line) < 16384:
        outfile.write(line)
infile.close()
outfile.close()

これは機能しますが、将来の参考のために、行の長さでファイルをフィルタリングする魔法の1行の呪文(awksedと考えてください)はありますか?

19
Li-aung Yip
awk '{ if (length($0) < 16384) print }' yourfile >your_output_file.txt

独自の例のように、16キロバイトより短い行を印刷します。

または、Perlが好きな場合:

Perl -nle 'if (length($_) < 16384) { print }' yourfile >your_output_file.txt
28

これはアンスガーの答えに似ていますが、私のテストでは少し高速です:

awk 'length($0) < 16384' infile >outfile

他のawkの回答と同じ速度です。真の式の暗黙のprintに依存しますが、Ansgarのように行を分割するために時間をかける必要はありません。

AWKはifを無料で提供します。上記のコマンドは次と同等です。

awk 'length($0) < 16384 {print}' infile >outfile

他のいくつかの回答のように、明示的なif(またはその周囲の波括弧)はありません。

sedでこれを行う方法は次のとおりです:

sed '/.\{16384\}/d' infile >outfile

または:

sed -r '/.{16384}/d' infile >outfile

16384(またはそれ以上)の文字を含む行を削除します。

完全を期すために、sedを使用してしきい値よりも長い行を保存する方法を次に示します。

sed '/^.\{0,16383\}$/d' infile >outfile

すでに与えられた答えと実際には違いはありませんが、まだ短いです:

awk -F '' 'NF < 16384' infile >outfile
2

次のようなawkを実行できます。

$ awk '{ if (length($0) < 16384) { print } }' /path/to/text/file

これにより、16K文字(16 * 1024)よりも短い行が印刷されます。

grepも使用できます:

$ grep ".\{,16384\}" /path/to/text/file

これにより、最大で16K文字の行が印刷されます。

2
Khaled