단일 명령은 두 문자열을 사용하여 두 문자열 사이의 문자열을 추출합니다(예: "tr"(표현식 없음))

단일 명령은 두 문자열을 사용하여 두 문자열 사이의 문자열을 추출합니다(예: "tr"(표현식 없음))

봤다여기sed를 사용하여 한 줄에 있는 다른 두 문자열 사이의 텍스트를 가져오는 방법입니다. 예를 들면 다음과 같습니다.

sed 's/.*starting_text\(.*\)ending_text.*/\1/'

tr하지만 두 개의 문자열만 사용하여 첫 번째 문자열 앞이나 두 번째 문자열 뒤의 모든 항목을 잘라내는 간단한 명령(예: 문자열 추출의 경우)을 원합니다.

grep something some_file | between message\"\:\" " with"

그리고 이스케이프 문자를 처리합니다.

답변1

구분 기호가 한 줄에 여러 번 나타날 수 있는 경우 대신 다음과 같이 Perl을 사용할 수 있습니다.

between() {
  perl -Tlne 'BEGIN{$b=shift;$e=shift}
             print for /\Q$b\E(.*?)\Q$e\E/g' "$@"
}

예를 들면 다음과 같습니다.

$ echo "[b]test[e] foo [b]bar[e]" | between '[b]' '[e]'
test
bar

다음과 같이 사용할 수도 있습니다.

between BEG END file1 file2...

답변2

일반적으로 sed에서 이 작업을 수행하려면 내가 찾은 하위 문자열을 찾는 데 사용되는 정규식에서 이스케이프 문자가 필요합니다.여기(참고: 추가 정보여기문제가 있는 경우).

그런 다음 함수에 파이프하는 방법을 알아냈습니다.여기.

이 모든 것을 my 에서 사용할 수 있는 함수로 합치면 .bashrc다음과 같습니다(a 및 b 변수를 설정할 필요는 없지만 읽기가 더 쉽습니다).

between(){
  a=$(printf '%s\n' "$1"|sed 's![\*.^$/[]!\\&!g')
  b=$(printf '%s\n' "$2"|sed 's![\*.^$/[]!\\&!g')
  sed "s/.*$a\(.*\)$b.*/\1/"
}

Joseph R.이 언급했듯이,이 답변grep -oP를 사용하여 유사한 작업을 수행하는 방법을 보여줍니다. Perl 호환 정규 표현식을 탈출하려면 다음을 발견했습니다.이것, 따라서 다음도 작동할 수 있습니다.

between(){
  a=$(printf '%s\n' "$1"|sed 's![]\*.^+?(){|$[]!\\&!g')
  b=$(printf '%s\n' "$2"|sed 's![]\*.^+?(){|$[]!\\&!g')
  grep -oP "(?=$a).*?(?=$b)"
}

관련 정보