data.txt
파일의 두 번째 열 매개변수 중 하나가 포함된 모든 줄을 삭제하고 싶습니다 keys.txt
.
keys.txt
2 aa 2 bb 2 cc 2 dd
data.txt
1 aa It is great 1 aa I want to delete this line 1 kk Really ? 1 bb Yes, I think so. 1 bb Why ? 1 kk Because I don't like the current situation 1 ll I want to change 1 cc Indeed it's a need 1 cc Sorry 1 zz Ok !
- 원하는 출력
1 kk Really ? 1 kk Because I don't like the current situation 1 ll I want to change 1 zz Ok !
다음 프로그램을 사용해 보았습니다 awk
.
awk '
NR == FNR {pattern[$0]; next}
{
for (var in pattern) {
if ($0 ~ var) {
getline
next
}
}
print >> GoodFile.txt
}
' keys.txt
답변1
당신은 꽤 가까웠지만 몇 가지 작은 점이 빠졌습니다.
data.txt
이를 호출에 매개변수로 추가 해야 합니다awk
. 그렇지 않으면 파일이 처리되지 않습니다.- 현재 전체 행을
keys.txt
삭제 데이터베이스에 등록하고 있으므로 두 번째 필드($2
대신$0
)로 제한해야 합니다. if ($0 ~ var)
행을 제외해야 하는지 확인하는 데 사용됩니다 .data.txt
여기에서도 행의 두 번째 필드만 비교해야 하며,==
키에 정규식 관련 문자가 포함될 수 있는 경우를 방지하려면 정규식 일치 대신 완전 일치( )를 사용해야 합니다.- 에서 인쇄
awk
하지만 꼭 그럴 필요는 없습니다. 대신 출력을 리디렉션할 수 있습니다.
따라서 약간 수정하면 다음과 같습니다.
awk 'NR==FNR{pattern[$2];next} !($2 in pattern)' keys.txt data.txt > GoodFile.txt
keys.txt
이는 배열의 각 행의 두 번째 열을 등록 pattern
하지만 파일에 대해 다른 작업은 수행하지 않습니다. 왜냐하면, data.txt
각 라인에 대해 조건이 평가되는 지점에 도달할 것이기 때문입니다 . !($2 in pattern)
조건이 "true"로 평가되는 경우(즉, 행의 두 번째 열이아니요배열의 인덱스에서 pattern
) 현재 행이 인쇄됩니다.
답변2
스크립트의 첫 번째 질문은 다음과 같습니다.
NR == FNR {pattern[$0]; next}
전체 행을 배열의 키로 사용 pattern
하지만 두 번째 필드만 필요합니다. 와 를 둘 다 사용할 필요 next
는 없고 그냥 다음 줄로 넘어가면 getline
됩니다 . next
또한 두 번째 파일을 입력으로 전달하는 것을 잊었습니다. 마지막으로 파일 이름은 변수가 아닌 문자열이므로 따옴표로 묶어야 합니다. 이 두 가지 오류를 수정하면 다음이 발생합니다.
awk '
NR == FNR {pattern[$2]; next}
{
for (var in pattern) {
if ($0 ~ var) {
getline
next
}
}
print >> "GoodFile.txt"
}
' keys.txt data.txt
지금 당신은틀림없이거기서 그걸 원하세요 >>
? 이는 awk
파일에 이미 있는 항목(예: 이전 실행의 출력)을 덮어쓰지 않음을 의미합니다. 단일 실행의 출력을 덮어쓰지 않으 >>
려면 필요하지 않습니다 . 이는 이전 실행의 데이터를 유지하려는 경우 에만 필요하지만 그렇지 않을 것 같습니다.awk
>
>>
또한 데이터를 기반으로 실제로 전체 행을 확인하고 싶지는 않습니다. data.txt
두 번째 필드가 의 두 번째 필드와 동일한 행만 건너뛰려고 합니다 keys.txt
. 그렇다면 특히 대용량 파일의 경우 더 효율적입니다.
awk '
NR == FNR {pattern[$2]; next}
{
if ($2 in pattern) {
next
}
print > "GoodFile.txt"
}
' keys.txt data.txt
또는 동등하지만 더 간결하게 말하면 다음과 같습니다.
awk '
NR == FNR {pattern[$2]; next}
{
if (!($2 in pattern) {
print > "GoodFile.txt"
}
}
' keys.txt data.txt
답변3
GNU sed
확장 정규식 모드 켜기 -E
, 자동 인쇄 모드 공백 끄기-n
$ sed -En '
/^\S+\s+(\S+)$/{
s//\1/;H;d
}
G
/^\S+\s+(\S+)\s.*\n\1(\n|$)/!P
' keys.txt data.txt
키 파일에 두 개의 필드가 있고 데이터 파일에 두 개 이상의 필드가 있다고 가정합니다.
첫 번째 단계에서는 key.txt 파일의 두 번째 필드를 보류 상태로 저장합니다. 그런 다음 data.txt 파일을 읽는 동안 data.txt 파일의 현재 레코드에 키를 추가하고 데이터의 두 번째 필드가 키의 어느 위치에서나 볼 수 있는지 비교합니다. 발견되지 않은 경우에만 데이터를 인쇄합니다.