아래와 같이 파이프로 구분된 파일이 있습니다.
데이터.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.txt
input.txt
이는 GNU sed 버전에 라인 노이즈를 줄이기 위해 확장 정규식이 활성화되어 있다고 가정합니다.