패턴까지 모든 것을 삭제하고 라인에서 다른 패턴 이후의 모든 것을 어떻게 삭제할 수 있습니까?


17

다음 파일에서 :

Lorem ipsum의 dolor는 amet, consectetuer adipiscing elit에 앉습니다. ut eu metus id lectus vestibulum ultrices. Maecenas 코뿔소.

전과 consectetuer후의 모든 것을 삭제하고 싶습니다 elit.

내 원하는 출력 :

consectetuer adipiscing elit.

어떻게해야합니까?


2
명령은입니다 sed. 또한 perl순수 bash 일 수도 있습니다 .
muru

@manuel이 답변 중 하나를 통해 문제를 해결 한 경우 잠시 시간을내어 왼쪽의 확인 표시를 클릭하여 수락하십시오 . 그러면 질문이 답변 된 것으로 표시되며 Stack Exchange 사이트에 감사가 표현되는 방식입니다.
terdon

답변:


27

나는 sed를 사용할 것이다

sed 's/^.*\(consectetuer.*elit\).*$/\1/' file

sed s / find / replace / 구문을 해독했습니다 :

  • s/^.*-줄의 시작 부분 ( ^) 부터 시작하여 그 뒤에있는 것 ( .*)까지 대체
  • \( -명명 된 블록을 시작
  • consectetuer.*elit\.-첫 단어, 모든 단어 ( .*)를 마지막 단어까지 일치시킵니다 (이 경우 마지막 이스케이프 포함)
  • \) -명명 된 블록을 종료
  • 다른 모든 항목 ( .*)을 줄 끝 과 일치 시킵니다 ( $)
  • / -대체 찾기 섹션을 종료하십시오.
  • \1- 이름 사이의 블록으로 교체 \(하고, \)상기
  • / -교체를 종료

1
좋은 대답은,하지만 당신은 필요하지 않습니다 ^또는 $나오지 이후 시도하고 가장 긴 일치를 찾을 수 있습니다. 또한 후 점을 놓쳤을 수 있습니다 . 필요한 경우 elit삽입 할 수 있습니다 \..
asoundmove

2
@asoundmove "elit"의 후행 점에 잘 맞습니다. -당신은 꽤 날카로운 눈을 가지고 있습니다!. 패턴에 이스케이프 된 점을 포함하도록 답변을 업데이트했습니다. 귀하는 또한 의문 사항 ^$필요하지 않음을 확인합니다-질문자가 원래 (원래) 약간 초보자라고 지적 했으므로 다른 맥락에서 도움이 될 수 있습니다.
MikeV

나는 항상 sed 솔루션을 복사하여 내 요구에 맞게 해킹했지만이 답변 덕분에 실제로 그것을 이해하는 것처럼 느낍니다. 큰 대답
타일러

7

모든 줄 에 시작과 끝 패턴이 모두 포함되어 있으면 가장 쉬운 방법은입니다 grep. 각 줄의 시작과 끝 을 삭제 하는 대신 두 패턴 사이의 내용을 간단히 출력 할 수 있습니다. -oGNU 의 옵션 grep은 일치하는 내용 만 출력합니다.

grep -o 'consectetuer.*elit' file

참고 : 언급했듯이 파일의 모든 줄을 이런 식으로 구문 분석 할 수있는 경우에만 작동합니다. 다시 말하지만, 이는 모든 일반적인 사용 사례의 80 %입니다.


1

AWK에서 두 개의 for 루프 :

$ awk '{for(i=1;i<=NF;i++) {if ($i == "consectetuer") beginning=i; if($i== "elit.") ending=i }; for (j=beginning;j<=ending;j++) printf $j" ";printf "\n"   }' file.txt 
consectetuer adipiscing elit.

AWK의 GSUB :

$ awk '{gsub(/^.*consectetuer/,"consectetuer"); gsub(/elit.*$/,"elit.");print}' file.txt
consectetuer adipiscing elit.

1

펄 방식. 이것은 본질적으로 MikeV의sed 답변 과 동일합니다 .

perl -pe 's/.*(consectetuer.*elit).*./$1/' file

-p수단 "으로 주어진 스크립트를 적용한 후 모든 라인을 인쇄 -e". 는 s/foo/bar/치환 연산자이며; 로 대체 foo됩니다 bar. 괄호는 패턴을 캡처하여 대체 패턴으로 사용할 수 있습니다. 첫 번째 캡처 패턴은 $1두 번째 $2입니다.

따라서 명령은 consectetuer( .*consectetuer) 까지의 모든 항목과 elit( .*elit)까지의 모든 항목, 그리고 줄 끝까지의 모든 항목 ( .*)을 일치시키고 캡처 된 패턴으로 대체합니다.


1

이 질문 제목이 왜 파일에서 " 줄에서 " 줄로 편집되었는지 왜 잘 모르겠지만 OP는 예제가 한 줄로만 보이지만 여러 줄의 가능성을 배제하지 않습니다. 어쨌든 여기에 여러 줄 솔루션을 제공하는 것이 도움이 될 수 있습니다.

이것은 크로스 라인에서 작동합니다.

from1=consectetuer; to2=elit; a="$(cat file)"; a="$(echo "${a#*"$from1"}")"; echo "$from1${a%%"$to2"*}$to2"

예 :

[xiaobai@xiaobai tmp]$ cat file
1
abc consectetuer lsl

home

def elit dd
2 consectetuer ABC elit
[xiaobai@xiaobai tmp]$ from1=consectetuer; to2=elit; a="$(cat file)"; a="$(echo "${a#*"$from1"}")"; echo "$from1${a%%"$to2"*}$to2"
consectetuer lsl

home

def elit
[xiaobai@xiaobai tmp]$ 

참조 : 쉘 매개 변수 확장


1
저건 완벽 해!
Clément
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.