6

パイプ|区切りファイルがあります。

ファイル:

106232145|"medicare"|"medicare,medicaid"|789

各行のフィールド数を数えたいと思います。以下のコードを試しました

コード:

awk -F '|' '{print NF-1}'

これは、結果を 4 ではなく 5 として返します。これは、awk が「medicare|medicaid」を 1 つのフィールドではなく 2 つの異なるフィールドとして受け取るためです。

4

5 に答える 5

5

純粋な Unix ソリューション (awk/Perl なし):

$ cat  /tmp/x1
1|2|3|34
4534|23442|1121|334434

$ head -1 /tmp/x1 | tr "|" "\012" | wc -l
4

Perl ソリューション - ワンライナー:

$ perl5.8 -naF'\|' -e 'print scalar(@F)."\n";exit;' /tmp/x1
4

しかし!!!!重要!!!

これらのソリューションはすべて、他の回答のソリューションと同様に、100%機能しません。

つまり、実際の CSV ファイルのように、パイプがフィールド (および引用符で囲まれたフィールド) で有効な文字である REAL の「パイプで区切られた」ファイルである場合、それらはすべて壊れます。

例えば

$ cat /tmp/x2
"0|1"|2|3|34
4534|23442|1121|334434
$ perl5.8 -naF'\|' -e 'print scalar(@F)."\n";exit;' /tmp/x1
5   <----- BROKEN!!! There are only 4 fields, first field is "0|1"

これを修正するには、Perl のような適切な CSV (または区切りファイル) パーサーを使用する必要があります。

$ perl5.8 -MText::CSV_XS 
-ne '$csv=Text::CSV_XS->new({sep_char => "|"});  $csv->parse($_); 
print $csv->fields(); print "\n"; exit;' /tmp/x2

正しい値を出力します

4

注意として、複雑な RegEx で単にawkorsedソリューションを修正するのは簡単ではありません。これは、パイプを含む引用符付きの PSV フィールドに加えて、仕様ではフィールドの一部として引用符も許可されているためです。それは、優れた正規表現ソリューションには向いていません。

于 2013-07-09T21:35:59.720 に答える
1
$ cat fieldparse.awk
#NR > 1 { print "--"; }

# Uncomment printf/print in the for loops to see
#   each field on a separate line as well as the commented line above (to show that it works).
{
    nfields = 0;
    for (i = 1; i <= NF; i++) {
        if ($i ~ /^".*[^"]$/)
            for (; i <= NF && ($i !~ /.*"$/); i++) {
                #printf("%s%s", $i, FS);
            }
        #print $i;
        nfields++;
    }
    print nfields;
    if (FILENAME == "-")
        FILENAME = "(standard input)";
    filenames[FILENAME] = sprintf("%d %d", FNR, nfields);
}

END {
    print NR, "total records processed";
    for (f in filenames) {
        split(filenames[f], fn, " ");
        printf("\t* %s: %d records with %d fields\n", f, fn[1], fn[2]);
    }
}

$ awk -F'|' -f fieldparse.awk demo.txt

二重引用符ではない単一文字の区切り記号、つまり標準のタブ区切り、CSV などの形式 (とにかく標準として...) で機能します。

出力形式は単なる説明であり、最後に少し装飾的ですが、コンテンツは複数のファイルを処理するなど、私見でも役立ちます。いずれにせよ、それが役立つことを願っています!:-)

編集

これは、mawk と GNU awk (gawk) を使用してテストされ、後者は従来の POSIX モードとデフォルト モードでテストされました。コメントと出力ステートメントをトリミングして、実際には小さなプログラムであることがわかりますが、好きなほど小さくはありません。

于 2013-07-10T02:45:30.090 に答える