grepなどを使用して1行ずつ処理するために、複数のハイフンおよび/またはスペースを含む文字列を解析する方法は?

grepなどを使用して1行ずつ処理するために、複数のハイフンおよび/またはスペースを含む文字列を解析する方法は?

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

関連情報