
data.csvとlist.txtという2つのファイルがあります。以下は、彼らがどのように見えるかについての例です。
データ.csv:
"John","red","4"
"Basketball","orange","2"
"The Mike","blue","94"
"Lizard","purple","3"
"Johnny","pink","32"
リスト.txt:
Mike
John
purple
32
では、ループの作り方を知りたいです。
awk -F "\"*,\"*" '/**LIST ITEM**/ {print $1}' data.csv > output.txt
このコマンドは list.txt の各行に対して実行され、**LIST ITEM**を置き換えます。これはどのように達成できますか?
私はMacOSX 10.5.7で端末を介してこれを実行しています。
編集する:
上記の例の望ましい出力は次のとおりです。
The Mike
John
Johnny
Lizard
Johnny
編集2:
もっと明確に言えば、私は次のことを避けようとしています。
awk -F "\"*,\"*" '/Mike/ {print $1}' data.csv
awk -F "\"*,\"*" '/John/ {print $1}' data.csv
awk -F "\"*,\"*" '/purple/ {print $1}' data.csv
awk -F "\"*,\"*" '/32/ {print $1}' data.csv
代わりに、list.txtのすべての行を繰り返すコマンドで実行してください。
答え1
これは所望の出力順序と一致する。
$ awk -F, '
NR == FNR {field1[$0] = $1; next}
{
for (line in field1)
if (line ~ $0)
print field1[line]
}
' data.csv list.txt
"The Mike"
"John"
"Johnny"
"Lizard"
"Johnny"
これは data.csv ファイルをメモリに読み込み、行全体を field1 にマップします。次に、list.txt ファイルの各行を field1 配列の各要素について確認します。
データファイルがリストファイルよりもはるかに大きい場合は、より小さなファイルをメモリに保持し、一度に1つずつ大きなファイルを繰り返す方が合理的です。
$ awk -F, '
NR == FNR {list[$1]; next}
{
for (item in list)
if ($0 ~ item)
print $1
}
' list.txt data.csv
"John"
"The Mike"
"Lizard"
"Johnny"
"Johnny"
答え2
#!/bin/bash
while read -r line; do
awk -F '^"|","|"$' '$0 ~ line{print $2}' line="$line" data.csv
done < list.txt
概念の証拠
$ while read -r line; do awk -F '^"|","|"$' '$0 ~ line{print $2}' line="$line" data.csv; done < list.txt
The Mike
John
Johnny
Lizard
Johnny
このフィールド区切り文字は、埋め込まれた引用符および/またはコンマを処理します。
答え3
何をしたいのか完全には明確ではありません。アイテム一覧何?どこでも一致するものを見つけて最初のフィールドを出力しますか?また、あなたの例は行list.txt
のどこでも一致しているように見え、これは問題になる可能性があります。list.txt
行がどの点に含まれるとどうなりますかe
?これは、例の最後の行を除くすべての項目と一致しますdata.csv
。
awk -F '^"?|"?,"?|"$?' 'BEGIN {
# read list.txt into an array
while (getline pat < "list.txt") {
pats[pat] = 1
}
close("list.txt")
}
{
# skip empty field before leading "
if ($1 == "") {
res = $2
} else {
res = $1
}
# scan record for patterns stored earlier,
# output the first real data field (res) if
# found
for (pat in pats) {
if ($0 ~ pat) {
print res
}
}
}' data.csv
これは思ったより少し複雑です。フィールド区切り文字は、最初のフィールドのオプションの先頭の引用符や最後のフィールドのオプションの後続の引用符を処理しません。私もそうですが、そこにあるコストのため、最初のフィールドは空になります(以前の空の文字列^"?
)。また、埋め込まれた引用符を処理しようとしません。任意の一般的なCSVをサポートする必要がある場合は、専用のCSVパーサーを使用することをお勧めします。