
#ファイル名を$1とする
#ビジネス名を$2
# $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
また、引用符で囲まれたフィールド(カンマを含む)を扱う必要がある場合は、テキスト::CSVCSV ファイルを解析するモジュール。 を使用してこれを行うこともできますawk
が、フィールド内の引用符とカンマを処理するために独自のパーサーを作成する必要があります。
Debian または類似の OS を実行している場合は、 でインストールします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
)。