web-dev-qa-db-ja.com

「N」フィールド以下または以下の行の削除?

私はMacでsed、Perl、awk、bashを使用しています。

TABで区切られたデータの13個のフィールド(列)を含む大規模な(10 GB)テキストファイルがあります。残念ながら、これらの行の一部には無関係なTABsが含まれているため、余分な部分がある行全体を削除するTABs、つまり、等しくないフィールドが必要です。 (行全体を破棄してもかまいません)

私が現在持っているものは、フィールドの数を別のファイルに書き込みます。

awk -F'\t' '{print NF}' infile  > fieldCount

head fieldCount
13
13
10
13
13
13
14
13
13
13

(元のファイルから)13を超える(または少ない)適切なフィールドを持つ行を削除する短いスクリプトを作成したいと思います。

  1. 複数のファイルでこれを実行する必要があるため、速度が役立ちます
  2. 1回のスイープでそれを行うと、クールになります
  3. 現在、fieldCountファイルをPythonに移植して、1行ずつロードしようとしています。

編集:

有効(13列)

a       b       c       d       e       f       g       h       i       j       k       l       m

無効(14列)

a       b       c       d       e       f       g       h       i       j       k       l       m       n
8
T. Scharf

あなたはほとんどそれをすでに持っています:

awk -F '\ t' 'NF == 13 {print}' infile新しいファイル

また、キーストローク(:)によって課金されるシステムの1つを使用している場合は、それを以下のように短縮できます。

awk -F '\ t' 'NF == 13' infile新しいファイル

1回のスイープで複数のファイルを実行し、実際にファイルを変更するには(新しいファイルを作成するだけでなく)、使用されていないファイル名(たとえば、scharf)を特定し、次のようなループを実行します。

f in リスト
 do 
 awk -F '\ t' 'NF == 13 {print}' "$ f"> scharf && mv -f-scharf "$ f" 
完了

listは、1つ以上のファイル名またはワイルドカードファイル名拡張パターン、あるいはその両方です。例えば、

blue.dataのfの場合green.data * .dat orange.data red.data /ultra/Violet.dat

mvコマンドは、一時ファイルscharfファイル(13個のフィールドを持つ入力ファイルからの行のみを含む)で入力ファイル(たとえば、_blue.data_)を上書きします。 (これが目的であることを確認し、注意してください。安全を確保するために、おそらく最初にデータをバックアップする必要があります。)_-f_は、mvに入力ファイルがすでに存在していても上書きするように指示します。 _--_は、ファイルに_-_で始まる名前が付いている場合に、奇妙さから保護します。

これは大きなファイルなので、パフォーマンスを向上させるには、もう少し複雑なツールを使用する価値があります。通常、専用ツールはジェネラリストツールよりも高速です。たとえば、同じ問題をcutで解決すると、grepよりも速くなる傾向があります。これは、sedより速くなる傾向があり、awkより速くなる傾向があります(逆に言えば、後のツールは前のツールではできないことを実行できるということです。

13文字以上のタブ文字を含む行を削除したいので、

LC_ALL=C grep -Ev '(␉.*){13}'

または多分(私は測定可能なパフォーマンスの違いを期待していません)

LC_ALL=C grep -Ev '(␉.*){12}␉'

どこ はリテラルのタブ文字です。ロケールをCに設定する必要はありませんが、マルチバイトロケールと比較して、GNU grepの一部のバージョンを高速化します。

Perlの場合:

Perl -F'\t' -anle 'print if @F == 13' file

インプレースで編集するには、-iオプションを追加します:

Perl -i.bak -F'\t' -anle 'print if @F == 13' file
1
cuonglm