세 번째 필드에 hotmail이라는 단어가 포함된 .txt 파일의 모든 이메일을 제거하려고 합니다. 현재 다음을 사용하려고 하는데 일부 행만 삭제됩니다. 왜인지는 모르겠지만
sed -i '/^[^,]*,[^,]*,[^,]*hotmail/d' *.txt
아래는 삭제되지 않은 줄 중 하나입니다.
"field1","field2.","[email protected]","whoeditedoutn.com","NeditedoutOW.COM|NeditedoutW.COM","editedout",""
"foo,bar","baz,qux","[email protected]","whoeditedoutn.com","NeditedoutOW.COM|NeditedoutW.COM","editedout",""
누구든지 나에게 올바른 명령을 내릴 수 있습니까? 또한 가능하다면 단어에 대문자와 소문자 hotmail
또는 HoTmAiL
다른 변형이 모두 포함되도록 주문하세요.
답변1
이는 CSV 파일이므로 필드 1과 2에 쉼표가 포함될 수 있습니다. 따라서 정규식 일치가 작동하지 않습니다. 적합한 CSV 파서가 필요합니다. 이것은 예이다
ruby -rcsv -ne 'row = CSV::parse_line($_); puts $_ unless row[2] =~ /hotmail/i' file
고쳐 쓰다: 이 Ruby 명령은 파일을 변경하지 않습니다. 위의 sed 명령도 마찬가지입니다. 변경 사항을 파일에 다시 저장하려면 이 -i
옵션을 사용하십시오. Pastebin 데이터 사용:
wc -l file
ruby -rcsv -i -ne 'row = CSV::parse_line($_); puts $_ unless row[2] =~ /hotmail/i' file
wc -l file
22 file
20 file
Perl에도 CSV 모듈이 있지만 표준은 아닙니다.CPAN에서 획득-- 오류 처리가 구현되지 않았습니다.
perl -MText::CSV -le '
$csv = Text::CSV->new({ binary=>1, always_quote=>1 });
open $fh, "<", shift(@ARGV);
while ($row = $csv->getline($fh)) {
$csv->print(STDOUT, $row) unless $row->[2] =~ /hotmail/i;
}
' file
답변2
해결방법을 문의하시면 sed
,
sed -n -e '/^"[^,]*","[^"]*",".*@hotmail/Ip' file
여기서는 삭제할 행만 인쇄합니다. 원래 선택으로 돌아가서 원하는 대로 정확하게 수행하세요. /Ip
다음으로 변경 하고 다시 /Id
변경-n
-i
/I
대소문자를 구분하지 않는 검색 제공
두 번째 필드는 [^"]
내부에 쉼표가 있는 필드가 분할되지 않도록 쉼표 대신 사용됩니다.
필드에 따옴표를 추가하고 도메인 이름 앞에 @를 추가하여 이메일 주소처럼 보이도록 했습니다.
업데이트: 이 버전은 @hotmail.com 뒤에 2개의 이메일 주소가 오는 것을 보장합니다. 즉, 처음으로 온라인에 접속한 것입니다.
세 번째 열에서 핫메일 주소를 검색합니다.
sed -n -e '/^"[^"]*","[^"]*","[email protected]",.+@.+,.+@.+$/Ip' file
이는 세 번째 열의 어느 곳에서나 핫메일에 적용되므로 Pastebin의 테스트 데이터에서도 작동합니다.
sed -n -e '/^"[^"]*","[^"]*",".*hotmail.+",.+@.+,.+@.+$/Ip' file
업데이트 2:
정규식을 다음과 같이 단순화했습니다.
sed -n -e '/^("[^"]*",){2}"[^"]*hotmail[^"]*"/Ip'