#ファイル名は$1です
#会社名は$ 2です。
#updated in theyear $3 #郵便番号と一致する V の前にある限り、引用された値内のすべてのコンマと一致します。すべてVで始まります。
./script6_1.sh bcindigenousbusinesslistings.csv "B.*" 2021
2020年以降に更新されたBで始まるすべてのビジネスを見つけます。
#最初のsedは2行目から最後の行までです。 #2番目のsed:行の先頭からV(郵便番号)までのすべてのパターンと一致することができ、その後は停止します。 $ 3最後の数字と一致するすべての数字と一致します。パターンは20(1〜3)と(0〜9)です。
*sed -n '2,$p' $1 | sed -e 's/^\('$2'[^,]*,[^,]*,[^,]*,.*[^V],\)\('$3'202[0-9]\)/\1\2/'*
要点は、それぞれカンマで区切られた3つの列を抽出することです。ビジネス、説明、住所。最後の列は更新年です。列の説明には、さらにカンマ区切り文字を含めることができます。
一致するパターンを抽出せずにすべての行を印刷するため、エラーが発生します。
ベストアンサー1
行全体の代わりに行内の列を使用するには、またはawk
よりperl
も優れたツールですsed
。
また、引用符を含むフィールド(コンマを含む)を処理する必要があるため、これを使用する方が良いですperl
。テキスト::CSVこのようなCSVファイルを解析するモジュールです。を使用してこれを実行できますが、awk
フィールド内の引用符とコンマを処理するには、独自のパーサーを作成する必要があります。
Debianまたは同様のものを実行している場合apt install libtext-csv-perl
。他のディストリビューションもパッケージ化できます。それ以外の場合は、を使用してインストールしてくださいcpan
。
以下は、詳細を取得するためにText::CSV
実行できるタスクの非常に簡単な例です。man Text::CSV
#!/usr/bin/perl
use strict;
use Text::CSV qw(csv);
my ($filename, $search, $year) = @ARGV;
my $csv = Text::CSV->new({allow_whitespace => 1,
allow_loose_quotes => 1,
quote_space => 0,
});
open(my $in, "<", $filename) or die "couldn't open $filename: $!";
my @headers = $csv->header($in);
pop @headers; # discard last field from @headers
$csv->say(*STDOUT, \@headers); # print the headers
while (my $row = $csv->getline($in)) {
# note: perl arrays start from zero, not one. So $row->[0] is
# the first field. $row->[3] is the fourth.
if ($row->[0] =~ m/$search/i && $row->[3] == $year) {
pop @{ $row }; # discard last field (year)
$csv->say(*STDOUT, $row);
}
}
close($in);
たとえば、別の名前で保存し、-を使用してシェルスクリプトと同じようにextract.pl
実行可能にします。chmod +x extract.pl
私はあなたの質問にサンプル入力や出力を提供していないので、ちょっとしたハットン音を作る必要がありました。
次の入力ファイルが与えられた場合input.csv
:
business,description,address,year
"ABC","sells some items","123 Somewhere Street, Somewhere, V1234",2020
"BCD Co.","sells some items","123 Somewhere Street, Somewhere, V1234",2021
"BBB Pty Ltd","sells some items","123 Somewhere Street, Somewhere, V1234",2020
"BXYZ","sells some items","123 Somewhere Street, Somewhere, V1234",2021
"CDE","sells some items","123 Somewhere Street, Somewhere, V1234",2020
"DEF","sells some items","123 Somewhere Street, Somewhere, V1234",2020
次の出力が生成されます。
$ ./extract.pl input.csv '^b' 2021
business,description,address
BCD Co.,sells some items,"123 Somewhere Street, Somewhere, V1234"
BXYZ,sells some items,"123 Somewhere Street, Somewhere, V1234"
つまり、2021年に「B」または「b」で始まるすべてのビジネス名です(正規表現の一致は大文字と小文字を区別しません)。最初の3つのフィールドのみが印刷されます。
出力が必要な場合(つまり、フィールド内にカンマがある場合)は、フィールドのみを参照する方法に注意してください。スペースを含むフィールドも引用するには、スクリプトでそれをquote_space => 0
次のように変更しますquote_space => 1
(またはスペースを含むフィールドを引用することがデフォルト値であるため、その行を削除しますText::CSV
)。