sed를 사용하여 목록 변수에서 줄 삭제

sed를 사용하여 목록 변수에서 줄 삭제

목록에서 단어가 포함된 줄을 삭제하기 위해 루프에서 sed를 사용하는 스크립트가 있습니다.

for i in $list; do
  sed -i "/$i/d" file
done

$listSQL 쿼리에서 생성됩니다.

list=$(psql -d dbname -t -c "SELECT foo from table ORDER BY column DESC")

문제는 우리 회사가 최근 all fchown또는 fchmodsyscall을 포함하는 더 엄격한 auditd 규칙을 구현했다는 것입니다. 을 사용하면 모든 항목에 1 과 syscall이 포함되어 있는 strace것을 볼 수 있습니다 .sed -ifchownfchmod

큰 목록 변수를 사용하면 iowaitauditd가 로그에 엄청나게 많은 행을 기록하기 때문에 급등하고 시스템이 실제로 정체됩니다.

목록 변수를 한 줄로 sed에 전달하여 파일이 한 번만 열리고 닫힐 수 있는 방법이 있는지 알아내려고 노력 중입니다.

이미 질문했는데 auditd 규칙에 대한 변경 사항은 시작이 아닙니다.

감사해요.

답변1

수많은 인라인 명령을 하나씩 호출하는 대신 한 번만 실행하고 sed단일 스크립트를 사용 하면 됩니다.sed

sedscript=$(mktemp)
for i in $list; do
  echo "/$i/d" >> "$sedscript"
done
sed -f "$sedscript" -i /path/to/file
rm -f "$sedscript"

답변2

의 단어를 주의 깊게 할당할 수 있다면 listbash 매개변수 확장을 사용하여 모든 공백을 정규식 alternator로 바꾼 다음 작업을 |요청할 수 있습니다.grep

list='auditd the to'
cp file temp &&  
grep -Ev "${list// /|}" temp > file && 
rm temp 

답변3

쉘이 배열을 지원하는 경우 다음과 같은 작업을 수행할 수 있습니다.

mapfile -t arr < <(psql -d dbname -t -c "SELECT foo from table ORDER BY column DESC")

명령의 출력을 쉘 배열에 넣으려면

printf '/%s/d\n' "${arr[@]}" | sed -i.bak -f - somefile

삭제 순서를 에 적용합니다 somefile. psql명령에서 반환된 필드에 에 특별한 문자가 포함될 수 있는 경우 일반적인 주의 사항이 적용됩니다 sed.

이는 임시 스크립트 파일을 피하고 필요한 경우 테이블 필드의 공백을 처리해야 한다는 점을 제외하면 @DopeGhoti의 솔루션과 유사합니다.

답변4

이것이 psql -d dbname -t -c "SELECT foo from table ORDER BY column DESC"공백으로 구분된 단어 목록을 제공하는 경우 다음을 시도하십시오.

$ psql -d dbname -t -c "SELECT foo from table ORDER BY column DESC" \
| awk -v FS=" " -v OFS="|" '{$1=$1; print "("$0")"}' \
| xargs -I {} sed -i -E '/{}/d' file

관련 정보