
#Dateiname als $1
#Firmenname als $2
#aktualisiert im Jahr $3 #Es kann mit jedem Komma in Anführungszeichen übereinstimmen, solange es vor dem entsprechenden V für die Postleitzahl steht. Sie beginnen alle mit V.
./script6_1.sh bcindigenousbusinesslistings.csv "B.*" 2021
Um alle Unternehmen zu finden, die mit B beginnen und im Jahr 2020 oder später aktualisiert wurden.
#Das erste sed ist von Zeile 2 bis zur letzten Zeile einzufügen. #Das zweite sed: Am Anfang der Zeile kann es mit jedem Muster bis zum V (Postleitzahl) übereinstimmen, dann wird es beendet. $3 stimmt mit jeder Zahl überein, die ein Muster von 20 (1 bis 3) und (0-9) für die letzte Ziffer hat.
*sed -n '2,$p' $1 | sed -e 's/^\('$2'[^,]*,[^,]*,[^,]*,.*[^V],\)\('$3'202[0-9]\)/\1\2/'*
Der Hauptpunkt besteht darin, 3 Spalten zu extrahieren, die jeweils durch Kommas getrennt sind. Unternehmen, Beschreibung, Adresse. Die letzte Spalte ist das Aktualisierungsjahr. Innerhalb der Spaltenbeschreibung können weitere Kommas verwendet werden.
Bei mir tritt dabei ein Fehler auf, da einfach die ganze Zeile ausgedruckt wird, ohne das passende Muster zu extrahieren.
Antwort1
Wenn Sie mit Spalten innerhalb einer Zeile statt mit der gesamten Zeile arbeiten möchten, ist awk
oder für diese Aufgabe ein viel besseres Werkzeug als .perl
sed
Und da Sie mit Feldern in Anführungszeichen (mit Kommas darin) zurechtkommen müssen, sollten Sie besser verwenden, perl
da es eineText::CSVModul, das CSV-Dateien auf diese Weise analysiert. Sie könnten dies mit tun awk
, aber Sie müssten Ihren eigenen Parser schreiben, um mit Anführungszeichen und Kommas in Feldern umzugehen.
Wenn Sie Debian oder ähnliches verwenden, installieren Sie es mit apt install libtext-csv-perl
. Andere Distributionen haben es wahrscheinlich auch im Paket. Andernfalls installieren Sie es mit cpan
.
Nachfolgend sehen Sie ein recht einfaches Beispiel dafür, was Sie mit tun können Text::CSV
. man Text::CSV
Für Details führen Sie es aus.
#!/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);
Speichern Sie dies beispielsweise als extract.pl
und machen Sie es mit ausführbar chmod +x extract.pl
– genauso, wie Sie es bei einem Shell-Skript tun würden.
Sie haben in Ihrer Frage keine Beispiele für Eingaben oder Ausgaben angegeben, deshalb musste ich mir irgendeinen Unsinn ausdenken.
Gegeben sei die folgende Eingabedatei 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
Es wird die folgende Ausgabe erzeugt:
$ ./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"
dh alle Firmennamen, die mit „B“ oder „b“ beginnen (bei der Regex-Übereinstimmung wird die Groß-/Kleinschreibung nicht berücksichtigt) mit dem Jahr 2021. Es werden nur die ersten 3 Felder gedruckt.
Beachten Sie, dass die Ausgabe nur dort in Anführungszeichen steht, wo es unbedingt nötig ist (d. h. wenn sich innerhalb der Felder Kommas befinden). Wenn Sie möchten, dass auch Felder mit Leerzeichen in Anführungszeichen stehen, ändern Sie quote_space => 0
dies quote_space => 1
im Skript in (oder löschen Sie diese Zeile einfach, da das Anführen von Feldern mit Leerzeichen die Standardeinstellung für ist Text::CSV
).