Unix - Sed 명령 관련

Unix - Sed 명령 관련

#파일 이름($1)

#비즈니스 이름은 $2입니다.

#$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

전체 라인이 아닌 라인 내부의 열로 작업하려면 다음 을 수행 awk하십시오 .perl would be a much better tool for this job than 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 => 1Text::CSV

관련 정보