grep 등을 사용하여 한 줄씩 처리하기 위해 여러 하이픈 및/또는 공백이 포함된 문자열을 구문 분석하는 방법은 무엇입니까?

grep 등을 사용하여 한 줄씩 처리하기 위해 여러 하이픈 및/또는 공백이 포함된 문자열을 구문 분석하는 방법은 무엇입니까?

RHEL 7 및 8에서 auditd 규칙을 사용하고 있습니다. 이러한 예제 파일을 고려하면...

파일 2.txt:

-a always,exit -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete
-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod
-a always,exit -F arch=b32 -S lchown,fchown,chown,fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod
-a always,exit -F arch=b64 -S chown,fchown,lchown,fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod
-a always,exit -F arch=b32 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod
-a always,exit -F arch=b64 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod
-w /etc/sudoers -p wa -k actions
-w /etc/sudoers.d/ -p wa -k actions

파일 1.txt:

-a always,exit -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete
-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod

나는 bash를 사용하여 이러한 파일을 프로그래밍 방식으로 구문 분석하여 file2.txt에 file1.txt의 줄이 포함되어 있는지 확인하려고 합니다. 그렇다면 해당 줄을 file2.txt에서 제거해야 합니다. 이 과정에서 file1.txt를 수정하고 싶지 않습니다.

원하는 출력:

파일 2.txt:

-a always,exit -F arch=b32 -S lchown,fchown,chown,fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod
-a always,exit -F arch=b64 -S chown,fchown,lchown,fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod
-a always,exit -F arch=b32 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod
-a always,exit -F arch=b64 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod
-w /etc/sudoers -p wa -k actions
-w /etc/sudoers.d/ -p wa -k actions

file1.txt(변경되지 않음):

-a always,exit -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete
-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod

나는 몇 가지 다른 방법을 시도했지만 아마도 이것이 내가 얻은 가장 가까운 방법일 것입니다(수동으로 바뀌었으므로 약간의 구문 오류를 양해해 주십시오).

# Write deltas to a temporary file
grep -f file2.txt file1.txt >> temp_file.txt

# For each line in the temporary delta file, delete that line from file2.txt
for i in $(cat temp_file.txt); do 
sed -i /"$i"/d file2.txt
done;

이렇게 하면 델타가 임시 파일에 저장되지만 대체가 작동하지 않습니다. 나는 탈출을 시도했다. 차이는 없었다.

sed -e expression #1: expected newer version of sed
sed -e expression #1: unknown command 'u'

이중 대시 이스케이프는 아무런 차이가 없는 것 같습니다. 예를 들면 다음과 같습니다.

sed -i -- /"$i"/d foo.txt

이를 위해 나는 인용되지 않은 시도도 했습니다.

sed -i /$i/d foo.txt

간단한 것이 빠진 것 같지만 이 문제로 몇 시간 동안 씨름했지만 아직 해결하지 못했습니다. 내가 뭘 잘못하고 있는지 아시나요?

답변1

grep -vxFf file1.txt file2.txt > tmp.txt && mv tmp.txt file2.txt

-F고정된 문자열을 나타내므로 특수 문자에 문제가 없습니다.

-v기존 명령과 반대되는 작업을 수행하므로 일치하지 않는 줄이 인쇄됩니다.

-x이는 전체 행만 일치시키려는 경우에도 필요합니다.


이에 상응하는 내용 awk은 다음과 같습니다.

awk 'FNR==NR{a[$0]; next} !($0 in a)' file1.txt file2.txt

관련 정보