sedまたはawkを使用してテキストファイルからCSVを生成する

sedまたはawkを使用してテキストファイルからCSVを生成する

そして列を含むCSVファイルを生成したいと思いますname。次のように見えます。foobar

name,foo,bar
a.txt,yes,no
b.txt,no,yes
c.txt,no,no

テキストファイルを含むディレクトリを繰り返して内容を解釈すると、CSVファイルが作成されます。

a.txtの内容は次のとおりです。

foo:yes
bar:no
baz:?

b.txtの内容は次のとおりです。

foo:no
bar:yes

c.txtの内容は次のとおりです。

foo
bar:no
baz:yes

熱があってはなりませんbaz。指定fooおよびbar。キーと値のペアも欠けているか不完全になる可能性があります(c.txtのように)。もしそうなら、no価値があるはずです。

orを使うawkと可能だと確信していますsedが、実装方法がわかりません。それは次のとおりです。

find . -name "*.txt" -print0 | xargs -0 -I {} sh -c "awk '...' {}"

ベストアンサー1

そのターゲットキーの1つ以上が入力ファイルに存在しない場合でも、各ターゲットキーの列を印刷したい場合:

$ cat tst.awk
BEGIN {
    numKeys = split("foo bar", tmp)
    for (i in tmp) {
        keys[i] = tmp[i]
    }
    FS=":"; OFS=","
}
{ fnameKey2val[FILENAME,$1] = $2 }
END {
    printf "%s%s", "name", OFS
    for (keyNr=1; keyNr<=numKeys; keyNr++) {
        key = keys[keyNr]
        printf "%s%s", key, (keyNr<numKeys ? OFS : ORS)
    }

    for (fileNr=1; fileNr<ARGC; fileNr++) {
        fname = ARGV[fileNr]
        printf "%s%s", fname, OFS
        for (keyNr=1; keyNr<=numKeys; keyNr++) {
            key = keys[keyNr]
            val = (fnameKey2val[fname,key] == "" ? "no" : fnameKey2val[fname,key])
            printf "%s%s", val, (keyNr<numKeys ? OFS : ORS)
        }
    }
}

または、特定のキーの列を印刷したくない場合(該当するキーがすべてのファイルに欠落している場合):

$ cat tst.awk
BEGIN {
    split("foo bar", tmp)
    for (i in tmp) {
        targets[tmp[i]]
    }
    FS=":"; OFS=","
}
!($1 in targets) { next }
!seen[$1]++ { keys[++numKeys] = $1 }
{ fnameKey2val[FILENAME,$1] = $2 }
END {
    printf "%s%s", "name", OFS
    for (keyNr=1; keyNr<=numKeys; keyNr++) {
        key = keys[keyNr]
        printf "%s%s", key, (keyNr<numKeys ? OFS : ORS)
    }

    for (fileNr=1; fileNr<ARGC; fileNr++) {
        fname = ARGV[fileNr]
        printf "%s%s", fname, OFS
        for (keyNr=1; keyNr<=numKeys; keyNr++) {
            key = keys[keyNr]
            val = (fnameKey2val[fname,key] == "" ? "no" : fnameKey2val[fname,key])
            printf "%s%s", val, (keyNr<numKeys ? OFS : ORS)
        }
    }
}

両方とも、与えられたサンプル入力から同じ出力を生成します。

$ awk -f tst.awk *.txt
name,foo,bar
a.txt,yes,no
b.txt,no,yes
c.txt,no,no

おすすめ記事