etc./StackOverFlow

특정 문자열을 포함하는 모든 행을 텍스트 파일에서 삭제하는 방법은 무엇입니까?

청렴결백한 만능 재주꾼 2021. 12. 8. 01:19
반응형

질문자 :A Clockwork Orange


sed를 사용하여 특정 문자열이 포함된 텍스트 파일의 모든 줄을 삭제하려면 어떻게 해야 합니까?



라인을 제거하고 출력을 표준 출력으로 인쇄하려면:

 sed '/pattern to match/d' ./infile

파일을 직접 수정하려면 – BSD sed에서는 작동하지 않습니다:

 sed -i '/pattern to match/d' ./infile

동일하지만 BSD sed의 경우(Mac OS X 및 FreeBSD) – GNU sed에서는 작동하지 않습니다.

 sed -i '' '/pattern to match/d' ./infile

파일을 직접 수정(및 백업 생성)하려면 – BSD 및 GNU sed와 함께 작동합니다.

 sed -i.bak '/pattern to match/d' ./infile

SiegeX

sed 외에 특정 문자열이 있는 줄을 삭제하는 다른 방법이 많이 있습니다.

AWK

 awk '!/pattern/' file > temp && mv temp file

루비(1.9+)

 ruby -i.bak -ne 'print if not /test/' file

 perl -ni.bak -e "print unless /pattern/" file

셸(bash 3.2 이상)

 while read -r line do [[ ! $line =~ pattern ]] && echo "$line" done <file > o mv o file

GNU 그렙

 grep -v "pattern" file > temp && mv temp file

그리고 물론 sed (역을 출력하는 것이 실제 삭제보다 빠름):

 sed -n '/pattern/!p' file

kurumi

sed를 사용하여 파일에서 줄을 바꿀 수 있습니다. 그러나 두 번째 파일에 대한 역함수에 grep을 사용한 다음 원본 위로 두 번째 파일을 이동하는 것보다 훨씬 느린 것 같습니다.

 sed -i '/pattern/d' filename

또는

 grep -v "pattern" filename > filename2; mv filename2 filename

어쨌든 내 컴퓨터에서는 첫 번째 명령이 3배 더 오래 걸립니다.


slashdottir

sed 를 사용하면 쉽게 할 수 있습니다.

 sed --in-place '/some string here/d' yourfile

Kevin Nguyen

ex (표준 Unix 명령 기반 편집기) 사용을 고려할 수 있습니다.

 ex +g/match/d -cwq file

어디:

  • + wq (쓰기 및 종료) -c 와 동일한 Ex 명령( man ex )을 실행합니다.
  • g/match/d match 줄을 삭제하는 Ex 명령, 참조: g의 거듭제곱

위의 예는 Unix.SE 및 ex 위한 POSIX 사양 에서 이 게시물에 따라 파일을 제자리에서 편집하기 위한 POSIX 호환 방법입니다.


sed 와의 차이점은 다음과 같습니다.

sed 는 파일 편집기가 아닌 S tream ED 편집기입니다. BashFAQ

이식할 수 없는 코드, I/O 오버헤드 및 기타 나쁜 부작용을 즐기지 않는 한. 따라서 기본적으로 일부 매개변수(예: in-place/ -i )는 비표준 FreeBSD 확장이며 다른 운영 체제에서는 사용하지 못할 수 있습니다.


kenorb

나는 Mac에서 이것으로 어려움을 겪었습니다. 또한 변수 교체를 사용하여 수행해야했습니다.

그래서 나는 다음을 사용했습니다.

sed -i '' "/$pattern/d" $file

여기서 $file 은 삭제가 필요한 파일이고 $pattern 은 삭제할 패턴입니다.

댓글 '' 를 선택했습니다.

여기서 주의할 점은 "/$pattern/d" 에서 큰따옴표 를 사용한다는 것입니다. 작은따옴표를 사용하면 변수가 작동하지 않습니다.


Aniket Sinha

다음을 사용할 수도 있습니다.

 grep -v 'pattern' filename

여기서 -v 는 패턴이 아닌 다른 항목만 인쇄합니다(즉, 일치 반전을 의미함).


Bhuvanesh

약 345,000줄이 포함된 파일로 작은 벤치마크를 만들었습니다. grep 하는 방법은 이 경우 sed 방법보다 약 15배 빠른 것 같습니다.

LC_ALL=C를 설정하거나 설정하지 않고 모두 시도했지만 타이밍이 크게 변경되지 않는 것 같습니다. 검색 문자열(CDGA_00004.pdbqt.gz.tar)은 파일 중간에 있습니다.

다음은 명령과 타이밍입니다.

 time sed -i "/CDGA_00004.pdbqt.gz.tar/d" /tmp/input.txt real 0m0.711s user 0m0.179s sys 0m0.530s time perl -ni -e 'print unless /CDGA_00004.pdbqt.gz.tar/' /tmp/input.txt real 0m0.105s user 0m0.088s sys 0m0.016s time (grep -v CDGA_00004.pdbqt.gz.tar /tmp/input.txt > /tmp/input.tmp; mv /tmp/input.tmp /tmp/input.txt ) real 0m0.046s user 0m0.014s sys 0m0.019s

Jadzia

grep 을 사용하여 inplace와 같은 결과를 얻으려면 다음을 수행할 수 있습니다.

 echo "$(grep -v "pattern" filename)" >filename

Jahid

SED:

엉엉:

그렙:


Oleg Mazko

perl -i -nle'/regexp/||print' file1 file2 file3 perl -i.bk -nle'/regexp/||print' file1 file2 file3

첫 번째 명령은 파일을 제자리(-i)에서 편집합니다.

두 번째 명령은 동일한 작업을 수행하지만 파일 이름에 .bk를 추가하여 원본 파일의 복사본 또는 백업을 유지합니다(.bk는 무엇이든 변경할 수 있음).


Kjetil S.

echo -e "/thing_to_delete\ndd\033:x\n" | vim file_to_edit.txt


Shizzmo

cat filename | grep -v "pattern" > filename.1 mv filename.1 filename

Andrey Izman

누군가가 문자열의 정확한 일치에 대해 수행하려는 경우를 대비하여 전체에 대해 grep -w 즉, 예를 들어 번호가 11인 행을 삭제하고 번호가 111인 행을 유지하려는 경우:

 -bash-4.1$ head file 1 11 111 -bash-4.1$ grep -v "11" file 1 -bash-4.1$ grep -w -v "11" file 1 111

여러 정확한 패턴을 한 번에 제외하려는 경우 -f 플래그와 함께 작동합니다. "블랙리스트"가 "파일"에서 삭제하려는 각 줄에 여러 패턴이 있는 파일인 경우:

 grep -w -v -f blacklist file

FatihSarigol

파일에서 라인 범위를 삭제할 수도 있습니다. 예를 들어 SQL 파일에서 저장 프로시저를 삭제합니다.

sed '/CREATE PROCEDURE.*/,/END ;/d' sqllines.sql

이렇게 하면 CREATE PROCEDURE와 END 사이의 모든 줄이 제거됩니다.

이 sed 명령으로 많은 SQL 파일을 정리했습니다.


GordyCA

처리된 텍스트를 콘솔에 표시하려면

 cat filename | sed '/text to remove/d'

처리된 텍스트를 파일에 저장하려면

 cat filename | sed '/text to remove/d' > newfile

처리된 텍스트 정보를 기존 파일에 추가하려면

 cat filename | sed '/text to remove/d' >> newfile

이미 처리된 텍스트를 처리하려면 이 경우 제거된 것 중 더 많은 줄을 제거하십시오.

 cat filename | sed '/text to remove/d' | sed '/remove this too/d' | more

| more 는 한 번에 한 페이지의 청크로 텍스트를 표시합니다.


nassim

흥미롭게도 수락 된 답변은 실제로 질문에 직접 답변하지 않습니다. 질문은 문자열 을 대체하기 위해 sed를 사용하는 것에 대해 묻지 만 대답은 임의의 문자열을 정규식 으로 변환하는 방법에 대한 지식을 전제로 하는 것 같습니다.

많은 프로그래밍 언어 라이브러리에는 이러한 변환을 수행하는 기능이 있습니다.

 python: re.escape(STRING) ruby: Regexp.escape(STRING) java: Pattern.quote(STRING)

그러나 명령줄에서 어떻게 합니까?

이것은 sed 지향적인 질문이므로 한 가지 접근 방식은 sed 자체를 사용하는 것입니다.

 sed 's/\([\[/({.*+^$?]\)/\\\1/g'

따라서 임의의 문자열 $STRING이 주어지면 다음과 같이 작성할 수 있습니다.

 re=$(sed 's/\([\[({.*+^$?]\)/\\\1/g' <<< "$STRING") sed "/$re/d" FILE

또는 한 줄로:

 sed "/$(sed 's/\([\[/({.*+^$?]\)/\\\1/g' <<< "$STRING")/d"

이 페이지의 다른 부분에 설명된 변형이 있습니다.


peak

일치하는 모든 파일에서 줄 삭제

 grep -rl 'text_to_search' . | xargs sed -i '/text_to_search/d'

djperalta

ed 를 사용하여 ex 를 사용하는 답변 과 비슷한 방식으로 파일을 편집할 수 있습니다. 이 경우의 가장 큰 차이점은 ed 가 ex와 같은 명령줄 인수가 아니라 표준 입력을 통해 명령을 ex 입니다. 스크립트에서 사용할 때 이를 수용하는 일반적인 방법은 printf 를 사용하여 명령을 파이프하는 것입니다.

 printf "%s\n" "g/pattern/d" w | ed -s filename

또는 heredoc으로 :

 ed -s filename <<EOF g/pattern/d w EOF

Shawn

출처 : http:www.stackoverflow.com/questions/5410757/how-to-delete-from-a-text-file-all-lines-that-contain-a-specific-string

반응형