입력 파일을 통해 텍스트 파일의 열에서 특정 값을 가진 행을 삭제하는 방법은 무엇입니까?

입력 파일을 통해 텍스트 파일의 열에서 특정 값을 가진 행을 삭제하는 방법은 무엇입니까?

아래와 같이 파이프로 구분된 파일이 있습니다.

데이터.txt

ESP|041336|46566|NY|CA
ESP|041337|46566|NY|CA
ESP|041338|46566|NY|CA
ESP|041339|46566|NY|CA
ESP|041340|46566|NY|CA
ESP|041341|46566|NY|CA

두 번째 열의 값을 제거해야 하는 또 다른 파일이 있습니다.

입력.txt

041337
041338
041339

두 번째 열에 input.txt 값이 있는 행을 삭제하려고 합니다.

예상 출력

ESP|041336|46566|NY|CA
ESP|041340|46566|NY|CA
ESP|041341|46566|NY|CA

나는 아래와 같이 이를 달성하기 위해 grep을 사용하려고 했습니다.

grep -vfw input.txt data.txt > output.txt

이렇게 하면 열이 제거되지 않지만 "해당 파일 또는 디렉터리가 없습니다"라는 오류가 발생하고 빈 파일이 반환됩니다.

답변1

비교를 두 번째 구분 필드로만 제한하려면 grep 대신 awk를 사용할 수 있습니다.

$ awk -F'|' 'NR==FNR {a[$1]++; next} !($2 in a)' input.txt data.txt > output.txt

$ cat output.txt
ESP|041336|46566|NY|CA
ESP|041340|46566|NY|CA
ESP|041341|46566|NY|CA

답변2

이 옵션에는 -f파일 이름이 필요합니다. 당신이 쓴 방식대로, 파일 이름은 이고 f, in 뒤의 텍스트는 -vfw즉, 입니다 w.

마지막에 매개변수와 함께 옵션을 넣어야 합니다(예외적으로 tar이상한 옵션 구문 분석을 사용함).

이들 중 하나라도 작동해야 합니다.

grep -v -w -f input.txt data.txt > output.txt
grep -vwf input.txt data.txt > output.txt
grep -vwfinput.txt data.txt > output.txt

참고: 질문할 때는 항상 정확한 오류 메시지 전체를 언급된 이름과 함께 인용해야 합니다 w.

grep: w: 해당 파일이나 디렉터리가 없습니다.

답변3

sed -nE '
   /\|/!{H;1h;d;}
   G
   /^[^|]+\|([^|]+)\|.*\n\1(\n|$)/!P
'  input.txt data.txt

결과:

ESP|041336|46566|NY|CA
ESP|041340|46566|NY|CA
ESP|041341|46566|NY|CA

논평:

  • input.txt그 안에 파이프가 없기 때문에 파이프는 예약된 공간에 저장됩니다. /\|/! 줄은 예약된 공간에서 개행 문자로 구분됩니다.

  • 데이터 행의 경우 예약된 영역을 패턴 공간에 추가한 다음 파이프로 구분된 두 번째 필드를 찾으려고 합니다. 찾을 수 없는 경우 첫 번째 개행 문자 앞의 패턴 공간 부분을 인쇄합니다 P.

    데이터 행(from)의 두 번째로 구분된 필드가 패턴 공간의 끝에 있고 줄 바꿈으로 구분된 입력 문자열 중 하나와 일치하는 경우 정규식은 /^[^|]+\|([^|]+)\|.*\n\1(\n|$)/패턴 공간과 일치합니다 . 일치하는 패턴이 파일의 마지막 줄인 경우를 처리하기 위해 끝에 OR 조건이 있습니다.|data.txtinput.txt

이는 GNU sed 버전에 라인 노이즈를 줄이기 위해 확장 정규식이 활성화되어 있다고 가정합니다.

관련 정보