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


답변:


2758

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

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

13
고맙지 만 파일에서 지우지 않는 것 같지만 해당 문자열없이 텍스트 파일 내용을 인쇄하십시오.
Clockwork Orange

115
@A Clockwork : 예, 출력을 새로운 파일로 리디렉션 sed '/pattern to match/d' ./infile > ./newfile하거나 내부 편집을 원한다면 -ised에 플래그를 추가 할 수 있습니다 sed -i '/pattern to match/d' ./infile. 이 -i플래그에는 GNU sed가 필요하며 이식성이 없습니다.
SiegeX

16
sed의 어떤 풍미를 위해; sed의 "-i"플래그는 확장 기능을 제공해야했습니다. (예 :) sed -i.backup '/pattern to match/d' ./infile그것은 바로 편집 할 수있게 해주었습니다.
avelis

9
@SiegeX 더 좋은 방법은, sed버전이 제어되지 않은 파일에는 명령을 적용하지 않는 것 입니다.
MatrixFrog 2013

84
Mac OS X 사용자를위한 참고 사항 : 어떤 이유로 든 -i 플래그는 빈 문자열 인 경우에도 인수를 전달해야합니다 sed -i '' '/pattern/d' ./infile.
geerlingguy

631

이외에도 특정 문자열이있는 행을 삭제하는 방법에는 여러 가지가 있습니다 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

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

그리고 물론 sed(역을 인쇄하는 것이 실제 삭제보다 빠릅니다) :

sed -n '/pattern/!p' file

4
패턴이있는 특정 줄과 그 바로 위에있는 줄을 삭제하는 방법? 다른 데이터 사이에 수천 줄이 있습니다.
oortcloud_domicile

1
OS / X에서 쉘 변형은 선행 공백을 유지하지 않지만 grep -v 변형은 나에게 효과적이었습니다.
Paul Beusterien

13
sed예는 다른 행동을 가지고, 그것은 단지 greps! 다음과 같아야 sed -n -i '/pattern/!p' file합니다.
caesarsol

8
모든 줄이 패턴과 일치하면 grep 버전이 작동하지 않습니다. 더 나은 방법 : grep -v "pattern" file > temp; mv temp file이것은 반환 값에 따라 다른 예제 중 일부에 적용될 수 있습니다.
Chris Maes

1
"반전 인쇄는 실제 삭제보다 빠릅니다"-내 컴퓨터에 없습니다 (2012 MacBook Air, OS X 10.13.2). 파일 작성 : seq -f %f 10000000 >foo.txt. sed d : time sed -i '' '/6543210/d' foo.txt실제 0m9.294 sed! p : time sed -i '' -n '/6543210/!p' foo.txt실제 0m13.671s. (파일이 작을수록 차이가 큽니다.)
jcsahnwaldt는 GoFundMonica가

252

sed를 사용하여 파일에서 줄을 바꿀 수 있습니다. 그러나 grep을 두 번째 파일로 반전 한 다음 두 번째 파일을 원본 위로 옮기는 것보다 속도가 훨씬 느린 것 같습니다.

예 :

sed -i '/pattern/d' filename      

또는

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

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


19
성능 비교를 시도한 이유만으로도 투표에 참여할 수 있습니다.
anuragw

4
grep 행으로 현재 파일을 덮어 쓰는 옵션을 제공하는 +1
Rhyuk

2
두 번째 'grep'솔루션은 대용량 파일에도 좋습니다
simoes

3
성능 차이가 무엇인지 궁금합니다.sed '/pattern/d' filename > filename2; mv filename2 filename
Pete

8
(ubuntu의 / usr / share / dict / words 사용) grep 및 mv : 0.010s | sed 제자리 : 0.197s | sed와 mv : 0.031s
ReactiveRaven

77

GNU로하는 쉬운 방법 sed:

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

55
이 Q & A 스레드를 우연히 발견하고 쉘 스크립팅을 처음 사용하는 다른 사람들을위한 유용한 팁 : 짧은 옵션은 명령 행에서 한 번만 사용하는 것이 좋지만, 읽기 쉬운 스크립트이므로 긴 옵션을 선호합니다.
Dennis

3
--in-place 플래그의 경우 +1 사용 권한으로 보호 된 파일에서 테스트해야합니다. (일부 사용자 스크러빙을 수행해야합니다.)
Bee Kay

8
long 옵션은 GNU sed에서만 사용할 수 있습니다. Mac과 BSD 사용자는이 방법으로 gsed를 설치해야합니다.
Matt

또 다른 팁 : 정규식이 일치하지 않으면 -r옵션을 사용하십시오 (또는 -E버전에 따라). 이 정규식 메타 문자의 사용을 가능하게 +, ?, {...}(...).
rjh

디스크에 여유 공간이없고 텍스트를 다른 파일로 복사 할 수없는 경우 정답입니다. 이 명령은 의문을 제기합니까?
ferreirabraga

38

다음을 사용 ex하는 것이 좋습니다 (표준 Unix 명령 기반 편집기 임).

ex +g/match/d -cwq file

어디:

  • +실행 (쓰기 및 종료)과 man ex동일하게 지정된 Ex 명령 ( ) -c을 실행합니다.wq
  • g/match/d-주어진 줄을 삭제하는 Ex 명령은 다음 match을 참조하십시오 : g의 거듭 제곱

위의 예는이 게시물에 따라 Unix.SEPOSIX 사양ex 의 파일을 편집하는 POSIX 호환 방법 입니다 .


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

sedA는 S tream ED 당사 홈페이지가 아닌 파일 편집기. BashFAQ

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


5
그게 대단합니다 ... 내가 man ex남자를 줄 때 vim, 그것은 exvim의 일부 인 것 같습니다 ... 바로 패턴 구문 matchvimregex.com 이라는 것을 이해한다면 POSIX 및 PCRE 풍미와 비슷하지만 다릅니다.
Anentropic

1
:g 약간의 차이 가있는 POSIX 호환 명령입니다 . PCRE가 기반이라고 가정합니다.
kenorb

16

나는 Mac에서 이것으로 고투하고 있었다. 또한 변수 교체를 사용하여해야했습니다.

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

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

where $file는 삭제가 필요한 파일이며 삭제 $pattern를 위해 일치시킬 패턴입니다.

''의견 에서를 선택했습니다 .

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


3
Mac sed은 뒤에 매개 변수가 필요 -i하므로 백업을 원하지 않으면 빈 문자열을 추가해야합니다.-i ''
wisbucky

쉘용 sed -i "/$pattern/d" $file. 답변 주셔서 감사합니다.
ashwaqar

14

약 345 000 줄을 포함하는 파일로 작은 벤치 마크를 만들었습니다. 이 방법 grepsed방법 보다 약 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

어느 플랫폼에 있습니까? 어떤 sed / perl / grep 버전을 사용하십니까?
hagello

내가 사용하는 플랫폼은 Linux (Gentoo)입니다. sed 버전은 GNU sed v 4.2.2, perl 버전 perl 5 (테스트 시점에 사용한 개정판을 알 수 없음) 및 grep (GNU)는 버전 3.0입니다.
Jadzia

14

이것을 사용할 수도 있습니다 :

 grep -v 'pattern' filename

여기서는 -v패턴 이외의 것만 인쇄합니다 (반전 일치).


특정 문자열을 포함하는 디렉토리에서 행을 삭제하는 방법
namannimmo

13

결과와 같은 결과를 얻으려면 grep다음을 수행하십시오.

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

4
이것은 bash쉘 또는 이와 유사한 경우에만 유용합니다 (아님 tcsh).
17:00에


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

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

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



2

누군가가 정확한 문자열 일치를 위해 그것을 원한다면, -wgrep-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한 번에 여러 개의 정확한 패턴을 제외하려는 경우 플래그 와 함께 작동합니다 . "blacklist"가 "file"에서 삭제하려는 각 행에 여러 패턴이있는 파일 인 경우 :

grep -w -v -f blacklist file

약간 오해의 소지가 있습니다. -w, --word-regexp Select only those lines containing matches that form whole words.vs.-x, --line-regexp Select only those matches that exactly match the whole line. For a regular expression pattern, this is like parenthesizing the pattern and then surrounding it with ^ and $.
Sai


0

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

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한 번에 한 페이지의 덩어리에 텍스트를 표시합니다.


0

당신은 오래된 좋은 사용할 수 있습니다 ed유사한 방식으로 편집에 파일을 대답 사용 ex. 이 경우 가장 큰 차이점은 ed표준 입력을 통해 명령을받는 것이 아니라 명령 줄 인수가 아니라는 것 ex입니다. 스크립트에서 스크립트를 사용할 때이를 수용하는 일반적인 방법은 printf명령을 파이프로 파이프하는 데 사용하는 것입니다.

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

또는 heredoc과 함께 :

ed -s filename <<EOF
g/pattern/d
w
EOF
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.