다음과 같이 자동으로 생성된 CSV 파일이 많이 있습니다.
1603145914502,48.12,0.085,s
1603145914815,48.12,0.020,s
1603145914941,48.12,0.019,s
1603145915404,48.12,0.031,s
1603145915612,48.12,0.033,s
1603145915899,48.12,0.019,s
정수, 두 개의 부동 소수점 숫자 및 문자.
빌드 중 스레딩 문제로 인해 일부 파일이 손상되었습니다.
1603145914502,48.12,0.085,s
1603145914815,48.12,0.020,s
1603145914941,48.12,0.019,s
1603145915404,48.12,0.031,s
1603145915612,48.12,0.033,s
1603145915899,48.12,0.019,s
1603145914502,48.12,0.085,s915899,48.12,0.019,s
1603145914815,48.12,0.020,s
1603145914941,48.12,0.019,s
1603145915404,48.12,0.031,s
1603145915612,48.12,0.033,s
1603145915899,48.12,0.019,s
1459143
1603145914815,48.12,0.020,s
1603145914941,48.12,0.019,s
1603145915404,48.12,0.031,s
형식에 맞지 않는 줄을 찾아 삭제하는 방법이 있나요? awk가 잘 할 수 있을 것 같지만 어떻게 사용하는지 전혀 모르겠습니다 :)
이를 수행할 수 있는 방법이 있다면 명령에서 뭔가를 배울 수 있도록 명령도 설명할 수 있다면 정말 감사하겠습니다.
편집: 형식을 명확히 하고 있습니다.
정수, 부동 소수점, 부동 소수점, 문자
쉼표 뒤에 공백이 있어서는 안 됩니다. 값은 위 형식을 준수하는 모든 값이 될 수 있습니다.
답변1
다음 단순/기본 형식(예: 부호 없음, 지수 없음)과 일치하는 데 필요한 것은 이들 중 하나뿐입니다 INT,FLOAT,FLOAT,CHAR
.
grep -E '^[0-9]+,([0-9]+\.[0-9]+,){2}[[:alpha:]]$' file
sed -En '/^[0-9]+,([0-9]+\.[0-9]+,){2}[[:alpha:]]$/p' file
awk '/^[0-9]+,([0-9]+\.[0-9]+,){2}[[:alpha:]]$/' file
답변2
형식에 맞지 않는 줄을 찾아 삭제하는 방법이 있나요?
여러 가지 방법이 있는데, 그 중 하나는 다음과 같습니다.
$ perl -n -i.bak -e 'print if /\d{13},\d\d.\d\d,\d\.\d\d\d,s$/' t.dat
$ diff t.dat.bak t.dat
7d6
< 1603145914502,48.12,0.085,s915899,48.12,0.019,s
13d11
< 1459143
$ cat t.dat
1603145914502,48.12,0.085,s
1603145914815,48.12,0.020,s
1603145914941,48.12,0.019,s
1603145915404,48.12,0.031,s
1603145915612,48.12,0.033,s
1603145915899,48.12,0.019,s
1603145914815,48.12,0.020,s
1603145914941,48.12,0.019,s
1603145915404,48.12,0.031,s
1603145915612,48.12,0.033,s
1603145915899,48.12,0.019,s
1603145914815,48.12,0.020,s
1603145914941,48.12,0.019,s
1603145915404,48.12,0.031,s
$
나는 awk/sed 이전에 perl을 사용하는 경향이 있지만 awk를 사용하여 거의 동일한 방식으로 동일한 작업을 수행할 수 있습니다.
해당 명령도 설명할 수 있으므로 그 명령에서 뭔가를 배울 수 있다면 정말 감사하겠습니다.
설명하다
-n
STDOUT으로 인쇄하지 않고 파일의 줄을 반복합니다.-i
그 자리에서 파일 편집-i.bak
그리고 실수할 경우를 대비해 지정된 파일 확장자를 가진 백업 복사본을 보관하세요!-e 'script'
스크립트에서 명령을 실행합니다(-n 옵션 뒤의 각 입력 줄에서).print if ...
조건식과 일치하면 해당 행을 인쇄합니다./ ... /
- 이것을 사용하세요정규식패턴 매칭을 위해^
줄의 시작 부분에...\d
숫자와 일치{3}
이전에 지정한 세 문자와 정확히 일치합니다.,
리터럴 쉼표 문자와 일치합니다.\.
리터럴 중지 문자와 일치합니다(그렇지 않으면.
와일드카드 메타 문자).s
리터럴 s 문자 일치$
줄의 끝과 일치합니다(즉, 줄에 더 이상 문자가 있을 수 없습니다.
보다 유연한 표현은 `^\d+,\d+.\d+,\d+.\d+,[a-zA-Z]$입니다.
+
적어도 하나의 이전 문자[...]
지정된 세트 중 하나[a-z]
a와 z(포함) 사이의 소문자 ASCII 문자[[:alpha:]]
POSIX 알파벳의 모든 문자\p{Lowercase_Letter}
모든 유니코드 문자소문자재산
Perl 정규식은 awk/grep에서 사용되는 정규식과 약간 다릅니다. 내 생각에 awk/grep의 최신 버전에는 Perl 스타일 정규 표현식을 사용할 수 있는 옵션이 있습니다. -P
grep 옵션은 매뉴얼 페이지를 참조하세요 .
답변3
# expect
# 1 2
# 123456789012345678901234567
# 160314591xxxx,48.12,0.0xx,s
grep -Ex '160314591[0-9]{4},48\.12,0\.0[0-9]{2},s' < file.csv
엄격한 매치가 진행됩니다. 일치시키려는 항목을 다소 제한적으로 정규식을 조정할 수 있습니다.