ヘッダー出力を持つ特定のフィールドに浮動小数点値が表示されないCSVファイルレコードのフィルタリング

ヘッダー出力を持つ特定のフィールドに浮動小数点値が表示されないCSVファイルレコードのフィルタリング

フィールドに浮動小数点値を含むCSVファイルのレコードをフィルタリングし、postal_codeヘッダーも出力に含めたいと思います。

サンプルCSVファイルは次のとおりです。

> ca  test.csv
employee_id|postal_code
1|56024.4 
1|752066

予想される出力は次のとおりです。

employee_id|postal_code
1|752066

私が試したこと:

> awk '$2 != "." {print $0} ' test.csv
1|56024.4
1|752066

答え1

コマンドは、awkスペースで区切られた2番目のフィールドがドットかどうかをテストします。 2番目のスペースで区切られたフィールドがないため、ファイルのすべての内容を出力します。


使用ミラーmlr()は、ドットを含むフィールド(ヘッダーなど)の出力からレコードをフィルタリングします。postal_codeca

$ mlr --csv --fs pipe filter -S '$postal_code !=~ "[.]"' file
employee_id|postal_code
1|752066

フィールド値を正規表現(で置換可能)と一致させてフィールド$postal_code !=~ "[.]"値をテストし、テストが成功した場合にレコードを削除するフィルタ式。postal_code[.]\.

この操作-Sのオプションはfilterフィールドの型推論をオフにするため、データはまだ浮動小数点ではない文字列です。

フィルタ式を使用して、フィールドに数字のみを含むレコードを$postal_code =~ "^[[:digit:]]+$"許可することもできます。postal_code特定の桁数(たとえば)を要求することで、これをより厳密にすることができます$postal_code =~ "^[[:digit:]]{6}$"

答え2

使用sed

$ sed -E '/[^|]*\|[0-9]+\./s/.*//' input_file
employee_id|postal_code

1|752066

答え3

または、次のように使用してくださいgrep

$ grep -P '.*\|[0-9]{5,9}$' test.csv
1|752066

編集する:OPの編集された質問に基づいて

$ sed -n -E '1p;2,${/^.+\|[0-9]{5,9}$/p}' test.csv
employee_id|postal_code
1|752066

通常のライナーでも同様のことができ、awk通常のライナーを使用する可能性はなくなりました。grep

編集する:タイミング情報の追加

$ time -p ( for i in {1..1000}; do 
               <command>
           done )

上記の<コマンド>を次に変更してください。

  • sed -n -E '1p;2,${/^.+\|[0-9]{5,9}$/p}' test.csv > /dev/null

    リアル3.10
    ユーザー2.19
    システム0.95

  • awk -F'|' 'NR==1;$2 !~ /[[:punct:]]/' test.csv > /dev/null

    リアル3.23
    ユーザー2.19
    システム1.06

  • mlr --csv --fs pipe filter -S '$postal_code !=~ "[.]"' test.csv > /dev/null

    リアル16.91
    ユーザー5.08
    システム12.37

答え4

このように:

$ awk -F'|' 'NR==1;$2 !~ /[[:punct:]]/' file
employee_id|postal_code
1|752066

関連情報