Unixスクリプトテーマで有効なファイルと無効なファイルを区別することはできません。

Unixスクリプトテーマで有効なファイルと無効なファイルを区別することはできません。

a.csvb.csvおよびという3つのファイルがありますc.csv

a.csv内容があります

1234567,11111111111111111111111111111111111111111111111111

b.csv同様の内容があります。

1234567845610111211111111111111111111111111

c.csv内容があります

111111,22222222,3333333,,,44444444444444444444

上記のa.csv3つのファイルのうち、2つの列を持つファイルにはnull値を含めないでください。残りのファイル(および)は、ファイルを含むb.csv他のテキストファイルc.csvの例にロードする必要があるという意味でのみ必要です。List.txtb.csvc.csv

,コンマ()なしでファイルを削除するために次のコマンドを試しましたが、うまくいかないこともb.csv考慮する必要があります。c.csv

grep -v "," *.csv |cut -d ":" -f1 

提案したように、次のコマンドを試しましたが、2つの値列を持つファイルが表示されます。

awk -F"," 'NF==2 {print FILENAME}' *.csv

ただし、無効なファイルを別のファイルに書き込む必要がある場合は、いくつかの提案を教えてください。

提案どおりに次のことを試しましたが、成功しませんでした。

ls | grep -v $(awk -F"," 'NF==2 {print FILENAME}') *.csv|sort -u

私も一度やってみるように勧めました。

awk -F',' 'BEGINFILE{ok=1}!$1||!$2||NF!=2{ok=0; nextfile}ENDFILE{if(!ok)print FILENAME}' *.csv

ただし、これにより次のエラーが発生します。

awk: A statement occurred that is not valid.

 The input line number is 1. The file is <Filename>
 The source line number is 1.

2番目のフィールド値は長さが250文字でa.csvb.csv...などのn個の値があります。

答え1

私が正しく理解したら、次のいずれかの条件で満足する行を含むファイルを削除したいと思います。

  1. フィールド 1 は空です。!$1
  2. フィールド 2 は空です。!$2
  3. 2つのフィールドはありません。NF!=2

それから

awk -F',' 'BEGINFILE{ok=1}!$1||!$2||NF!=2{ok=0; nextfile}ENDFILE{if (ok) print FILENAME}' *.csv

ok=1フラグを設定し、上記のいずれかの条件が満たされるまで各行を繰り返し、「間違った」行が見つかった場合はファイルを無効にし、行を解析せずにファイルの末尾ok=0にジャンプしますnextfile

各ファイルの終わりにゼロ以外の場合にのみENDFILE印刷されます。FILENAMEif (ok)

したがって、一致を無効にするには、最後のテストを反転してif (!ok)印刷するだけです。

awk -F',' 'BEGINFILE{ok=1}!$1||!$2||NF!=2{ok=0; nextfile}ENDFILE{if (!ok) print FILENAME}' *.csv

編集する

出力でエラーを再現することはできませんgawk(ファイル名をxxx.fileにリダイレクトするなど、以下を参照)。

bash --version
GNU bash, version 5.0.16(1)-release (x86_64-pc-linux-gnu)

awk --version
GNU Awk 5.1.0, API: 3.0 (GNU MPFR 4.0.2, GNU MP 6.2.0)

tail -n +1 *.csv; 
  awk -F',' 'BEGINFILE{ok=1}
    !$1||!$2||NF!=2{ok=0; nextfile}
  ENDFILE{gzout=(ok)?"ok":"banjaxed"; print FILENAME > gzout".files"}' *.csv ; 
tail -n +1 *.files

==> a.csv <==
1234567,11111111111111111111111111111111111111111111111111

==> b.csv <==
1234567845610111211111111111111111111111111

==> c.csv <==
111111,22222222,3333333,,,44444444444444444444

==> banjaxed.files <==
b.csv
c.csv

==> ok.files <==
a.csv

単一フィールド長制限(1024)問題にならないでくださいawk3,000文字のレコード制限に違反しない限り、この場合、awkどちらもsed操作に適したツールではないようです。

答え2

あるいは、grepどちらも使用できず、次のものがあると仮定して使用してくださいsedgrep数千あたりのファイル数数千grep行がかなり長いので、行全体をpingするのではなく、各行の最初の行だけを確認したいと思います。

すべての最初の行(ファイル名を含む)をインポートしてファイルに入れます。

head -n1 *.csv > list

各項目には、次のようにコンテキスト(ファイル名)行、最初の行、その後に空白行があります。

==> a.csv <==
1234567,11111111111111111111111111111111111111111111111111

==> b.csv <==
1234567845610111211111111111111111111111111

線に合ったパターンがあることがわかっているので、^[0-9.]+,[0-9.]+$次のことができます。

grep -E -B1 "^[0-9]+,[0-9]+$" list | grep -oP "(?<= )[^, <]+" > ok.list

1 つ目は前のコンテキスト行grep(一致するファイル名を含む) から一致を抽出し、2 番目はファイル名を抽出して目的のファイルにダンプします。list-B1ok.list

ok.list最後に、以下を使用してフィルタリングできます。

ls *.csv | grep -Fvxf ok.list > banjaxed.list

固定文字列(正規表現ではありません)「-F」のファイルを使用してファイルをgrepフィルタリングでき、完全一致はファイルを一致させるパターンのリストとして使用し、もちろん逆方向一致はフィルタ処理されたファイル列をOutにリダイレクトします。ok.listls-x-f-vbanjaxed.list

それが少なくともお金の価値がない場合、私はおもちゃを取り除きます。

関連情報