Unix - Связанные команды Sed

Unix - Связанные команды Sed

#имя_файла как $1

#название компании как $2

#обновлено в году $3 #Может соответствовать любым запятым внутри кавычек, если они находятся перед соответствующим V для почтового индекса. Все они начинаются с V.

./script6_1.sh bcindigenousbusinesslistings.csv "B.*" 2021

Чтобы найти все компании, которые начинаются на букву B, обновленные в 2020 году или позже.

#Первый sed помещает данные со строки 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"

т. е. все названия компаний, начинающиеся с «B» или «b» (соответствие регулярному выражению нечувствительно к регистру) с годом 2021. Печатаются только первые 3 поля.

Обратите внимание, что вывод содержит кавычки полей только там, где это необходимо (т. е. там, где внутри полей есть запятые). Если вы хотите, чтобы поля, содержащие пробелы, также были кавычками, измените quote_space => 0на quote_space => 1в скрипте (или просто удалите эту строку, поскольку кавычки полей с пробелами используются по умолчанию для Text::CSV)

Связанный контент