Unix 스크립트 테마에서 유효한 파일과 유효하지 않은 파일을 구별할 수 없습니다.

Unix 스크립트 테마에서 유효한 파일과 유효하지 않은 파일을 구별할 수 없습니다.

a.csv, b.csv및 이라는 세 개의 파일이 있습니다 c.csv.

a.csv내용이 있습니다

1234567,11111111111111111111111111111111111111111111111111

b.csv비슷한 내용이 있어요

1234567845610111211111111111111111111111111

c.csv내용이 있습니다

111111,22222222,3333333,,,44444444444444444444

위에서 언급한 세 개의 파일 중 a.csv두 개의 열이 있는 파일에는 null 값이 포함되어서는 안 되며 나머지 파일( b.csv및 )은 및 파일이 있는 다른 텍스트 파일 예제 c.csv에 로드되어야 한다는 의미로만 이것이 필요합니다.List.txtb.csvc.csv

,쉼표() 없이 파일을 삭제하기 위해 다음 명령을 시도했지만 작동하지 않는 것도 b.csv고려해야 합니다.c.csv

grep -v "," *.csv |cut -d ":" -f1 

제안한 대로 다음 명령을 시도했는데 두 개의 값 열이 있는 파일이 표시됩니다.

awk -F"," 'NF==2 {print FILENAME}' *.csv

하지만 유효하지 않은 파일을 다른 파일에 써야 할 경우 몇 가지 제안 사항을 알려주십시오.

제안된 대로 다음을 시도했지만 성공하지 못했습니다.

ls | grep -v $(awk -F"," 'NF==2 {print FILENAME}') *.csv|sort -u

나도 한번 해보라고 권유받았는데

awk -F',' 'BEGINFILE{ok=1}!$1||!$2||NF!=2{ok=0; nextfile}ENDFILE{if(!ok)print FILENAME}' *.csv

그러나 이로 인해 다음과 같은 오류가 발생합니다.

awk: A statement occurred that is not valid.

 The input line number is 1. The file is <Filename>
 The source line number is 1.

두 번째 필드 값은 길이가 250자이고 a.csv, b.csv... 와 같은 n개 값이 있습니다.

답변1

내가 올바르게 이해했다면 다음 조건 중 하나라도 만족하는 줄이 포함된 파일을 삭제하고 싶을 것입니다.

  1. 필드 1이 비어 있습니다.!$1
  2. 필드 2가 비어 있습니다.!$2
  3. 2개의 필드가 없습니다.NF!=2

그 다음에

awk -F',' 'BEGINFILE{ok=1}!$1||!$2||NF!=2{ok=0; nextfile}ENDFILE{if (ok) print FILENAME}' *.csv

ok=1플래그를 설정한 다음 위의 조건 중 하나가 충족될 때까지 각 줄을 반복하고, "잘못된" 줄이 발견되면 파일을 무효화 ok=0하고 더 이상 줄을 구문 분석하지 않고 파일 끝으로 점프합니다 nextfile.

각 파일의 끝에서 0이 아닌 경우에만 ENDFILE인쇄됩니다 .FILENAMEif (ok)

따라서 일치를 무효화하려면 마지막 테스트를 반전하여 if (!ok)인쇄 하면 됩니다.

awk -F',' 'BEGINFILE{ok=1}!$1||!$2||NF!=2{ok=0; nextfile}ENDFILE{if (!ok) print FILENAME}' *.csv

편집하다

출력에서 오류를 재현할 수 없습니다 gawk(파일 이름을 xxx.file로 리디렉션하는 것을 포함하여 아래 참조).

bash --version
GNU bash, version 5.0.16(1)-release (x86_64-pc-linux-gnu)

awk --version
GNU Awk 5.1.0, API: 3.0 (GNU MPFR 4.0.2, GNU MP 6.2.0)

tail -n +1 *.csv; 
  awk -F',' 'BEGINFILE{ok=1}
    !$1||!$2||NF!=2{ok=0; nextfile}
  ENDFILE{gzout=(ok)?"ok":"banjaxed"; print FILENAME > gzout".files"}' *.csv ; 
tail -n +1 *.files

==> a.csv <==
1234567,11111111111111111111111111111111111111111111111111

==> b.csv <==
1234567845610111211111111111111111111111111

==> c.csv <==
111111,22222222,3333333,,,44444444444444444444

==> banjaxed.files <==
b.csv
c.csv

==> ok.files <==
a.csv

단일 필드 길이 제한(1024)문제가 되어서는 안 된다awk3,000자 레코드 제한을 위반 하지 않는 한 , 이 경우 awk둘 다 sed작업에 적합한 도구가 아닌 것 같습니다.

답변2

대안으로, grep어느 쪽도 사용할 수 없으며 다음이 있다고 가정하고 사용 하십시오 sed.grep수천당 파일 수수천grep줄이 상당히 길기 때문에 줄 전체를 핑하는 대신 각 줄의 첫 번째 줄만 확인하고 싶을 것입니다 .

모든 첫 번째 줄(파일 이름 포함)을 가져와서 파일에 넣습니다.

head -n1 *.csv > list

각 항목에는 아래와 같이 컨텍스트(파일 이름) 줄, 첫 번째 줄, 그 뒤에 빈 줄이 있습니다.

==> a.csv <==
1234567,11111111111111111111111111111111111111111111111111

==> b.csv <==
1234567845610111211111111111111111111111111

선에 맞는 패턴이 이라는 것을 알고 있으므로 ^[0-9.]+,[0-9.]+$다음을 수행할 수 있습니다.

grep -E -B1 "^[0-9]+,[0-9]+$" list | grep -oP "(?<= )[^, <]+" > ok.list

첫 번째는 이전 컨텍스트 줄 grep(일치하는 파일 이름 포함)에서 일치 항목을 추출하고, 두 번째는 파일 이름을 추출하여 원하는 파일에 덤프합니다.list-B1ok.list

ok.list마지막으로 다음을 사용하여 필터링 할 수 있습니다 .

ls *.csv | grep -Fvxf ok.list > banjaxed.list

고정 문자열(정규식 아님) "-F"의 파일을 사용하여 파일을 grep필터링할 수 있고, 완전 일치는 파일을 일치시킬 패턴 목록으로 사용하며, 물론 역방향 일치는 필터링된 파일 열을 Out로 리디렉션하게 됩니다.ok.listls-x-f-vbanjaxed.list

그것이 적어도 돈의 가치가 없다면, 나는 장난감을 치울 것입니다.

관련 정보