Unix - Sed 命令相关

Unix - Sed 命令相关

#文件名为$1

#企业名称为 $2

#updated in theyear $3 #它可以匹配引号值内的任何逗号,只要它位于匹配邮政编码的 V 之前即可。它们都以 V 开头。

./script6_1.sh bcindigenousbusinesslistings.csv“B.*”2021

查找2020年或以后更新的所有以B开头的商家。

#第一个 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

如果您想使用一行内的列而不是整行,那么awkorperl将是比 更好的工具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与 shell 脚本相同。

您没有在问题中给出示例输入或输出,所以我不得不编造一些废话。

给定以下输入文件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 => 0quote_space => 1(或者删除该行,因为使用空格引用字段是默认的Text::CSV

相关内容