File1
고정 길이 숫자가 있으며 한 줄에 숫자가 하나씩 있습니다.
1234
5678
1345
File2
"key=value" 형식의 데이터 필드를 포함합니다.
abc:def=1999,xyz=1234;
abc:def=5678,xyz=1234;
abc:def=1234,xyz=5678;
필드가 의 숫자와 일치하는 행을 가져와야 File2
하지만 패턴 일치 중에 필드가 무시 됩니다 def
. 따라서 내 결과는 다음과 같아야 합니다.File1
xyz
abc:def=5678,xyz=1234;
abc:def=1234,xyz=5678;
답변1
나는 항상 대부분의 awk
명령을 잊어버리고 그것은 내 오래된 두뇌에 너무 부담스럽기 때문에 대안을 제공합니다 sed
.
sed '/^[0-9]*$/H;G;/def=\([0-9]*\),.*\n\1/P;d' file1 file2
아이디어는 예약된 공간에서 숫자를 수집 file1
하고 역참조를 사용하여 다음 숫자가 포함된 file2의 해당 행을 식별하는 것입니다.def=
- 이 패턴은
^[0-9]*$
숫자만 포함된 행과 일치합니다. 이는 행이며 이전 공간file1
에 추가합니다.H
G
예약된 공간을 패턴 공간에 추가하여 패턴 공간에file2
행과 모든 숫자를 갖게 됩니다.file1
- 이 패턴은 개행 문자 뒤에
/def=\([0-9]*\),.*\n\1
다음 숫자(역참조)가 반복되는 모든 행을 처리합니다(따라서 예약된 공간 집합의 일부임). 추가 내용 없이 줄 인쇄def=
\1
P
d
추가 출력을 억제합니다.-n
대신 옵션을 사용할 수 있습니다
업데이트: 시각적 설명
Ed가 지적했듯이, 내 설명은 분명히 모든 사람에게 도움이 되지는 않을 것입니다. 당신이 "시각적 사고"에 더 가깝다면 이것이 어떻게 작동하는지 설명하려고 노력할 것입니다. 이것은 sed
프로그래밍 도구가 아니라 다음 기능을 갖춘 자동 텍스트 편집기에 가깝습니다.예비 공간줄을 읽는 동안 "클립보드"로 사용패턴 공간, 작업이 완료된 곳입니다.
이제 제안된 대로 H
및 명령 G
뒤에 두 개의 공백을 표시합니다 .
패턴 공간 | 예비 공간 | 논평 |
---|---|---|
1234 |
1234 |
H (빈) 예약된 공간에 추가 하고 줄 바꿈 포함 |
1234 1234 |
1234 |
G 패턴 공간에 다시 추가하고 또 다른 개행을 추가합니다. |
5678 |
1234 5678 |
다음 줄을 읽을 때 예약된 공간이 유지되므로 다음 줄 H 에는 다음 번호가 추가됩니다. |
5678 1234 5678 |
1234 5678 |
패턴 공간에 다시 추가되지만 여전히 def= 패턴과 일치하지 않습니다. |
file1 가독성을 위해 세 번째 줄을 건너뛰세요. |
||
abc:def=1999,xyz=1234; |
1234 5678 |
패턴과 일치하지 않으므로 ^[0-9]*$ 실행 H 되지 않습니다. |
abc:def=1999,xyz=1234; 1234 5678 |
1234 5678 |
하지만 G 처형됐다 |
P
이제 명령의 주소 패턴을 적용하는 방법을 살펴보십시오( \n
개행 문자의 자리 표시자로 사용됨).
abc:def=1999,xyz=1234;\n\n1234\n5678
def=####, .* #### stands for `[0-9]*`, but the back reference
as `\1` is not found: no match
abc:def=5678,xyz=1234;\n\n1234\n5678
def=####, .* \n#### here, the match is repeated as `\1`,so we know
the `def` number has been listed in `file1`
답변2
숫자를 해시( nums
이 경우)로 수집하고 이를 사용하여 나중에 쉽게 찾을 수 있습니다.
awk -F '[=,;]' 'FNR==NR { nums[$1]; next } $2 in nums' file1 file2
산출:
abc:def=5678,xyz=1234;
abc:def=1234,xyz=5678;
필드 순서가 일정하지 않은 경우 다음 접근 방식을 사용할 수 있습니다.
awk -F'[=,;:]' '
FNR==NR { nums[$1]; next }
$2 == "def" && ($3 in nums) || $4 == "def" && ($5 in nums)
' file1 file2
답변3
grep -f <(sed 's/^/abc:def=/' file1.txt) file2.txt
또는 쉘이 이를 지원하지 않는 경우 새 파일을 생성할 수 있습니다 <()
.
sed 's/^/abc:def=/' file1.txt > patterns.txt
grep -f patterns.txt file2.txt
또는 fifo 파일을 만들 수 있습니다.
mkfifo fifo
sed 's/^/abc:def=/' file1.txt >fifo &
grep -f fifo file2.txt