컷/느낌표를 구분 기호로 사용

컷/느낌표를 구분 기호로 사용

Bash가 아닌 쉘에는 구문 분석하려는 다음과 같은 문자열이 있습니다.

stringhere/morestring!99

99구문 분석 후 문자열의 끝 부분을 유지하고 나머지 문자열을 삭제하고 싶습니다 .

유지해야 하는 하위 문자열의 길이가 항상 2자인 것은 아닙니다. !문자열 끝 부터 하나 이상의 숫자 또는 입니다 ,.

입력/출력 예:

In: stringhere/morestring!99
Out: 99

In: string/more!99,string/more!98,string/more!97
Out: 99

cut!문자열 중간을 제외하고는 뭔가 분명한 것처럼 들립니다 .

찾을 수 있는 단축키가 있나요? 더 좋아 질까 awk?

답변1

문자열이 FILE에 있고 항상 첫 !번째 숫자 뒤와 앞의 첫 번째 숫자 만 필요한 ,경우 해당 숫자가 있으면 작동합니다.

awk -F'[!,]' '{print$2}' FILE

!또는 구분 기호로 사용 하고 및 사이의 첫 번째 숫자 또는 바로 뒤에 ,오는 두 번째 필드를 표시합니다.!,! ,줄 안이나 앞에 아무것도 없는 경우.

,위의 첫 번째 !awk 예제가 이전에 있었던 경우에는 적용되지 않습니다.

하나의 명령을 다른 명령으로 파이프 할 수도 있습니다 cut. 먼저 이를 !구분 기호로 지정하고 첫 번째 명령 다음에 내용을 가져온 !다음 두 번째 명령에서 이를 ,구분 기호로 지정하고 첫 번째 명령 이전에 내용을 가져옵니다( ,존재하는 경우).

cut -d'!' -f2 FILE | cut -d',' -f1

답변2

사용할 수 있지만 cut두 번의 패스가 필요합니다. 첫 번째는 첫 번째 이후에 오는 것을 가져오고 !두 번째는 이후의 모든 것을 삭제합니다 ,.

$ echo 'string/more!99,string/more!98,string/more!97' | 
    cut -d'!' -f2- | cut -d, -f1
99

다시 말하지만, 그렇지 않은 경우( ,두 번째 것은 여기서 필요하지 않으며 정확히 동일한 명령을 사용할 수 있음을 보여주기 위해 추가했습니다):cut

$ echo 'string/more!99' | cut -d'!' -f2- | cut -d, -f1
99

또 다른 옵션은 다음과 같습니다 sed.

$ echo 'string/more!99,string/more!98,string/more!97' | 
    sed -E 's/^[^!]+!([0-9]+).*/\1/'
99
$ echo 'string/more!99' | sed -E 's/^[^!]+!([0-9]+).*/\1/'
99

또는 perl:

$ echo 'string/more!99,string/more!98,string/more!97' | 
    perl -pe 's/.+?!(\d+).*/\1/'
99
$ echo 'string/more!99' | perl -pe 's/.+?!(\d+).*/\1/'
99

아니면 GNUgrep

$ echo 'string/more!99,string/more!98,string/more!97' | 
    grep -oP '^[^!]+!\K\d+'
99
$ echo 'string/more!99' | grep -oP '^[^!]+!\K\d+'
99

답변3

필요한 것은 쉘의 인수 확장 구문뿐입니다. 이는 다음에서 찾을 수 있습니다.

$ input='stringhere/morestring!99'
$ echo "${input#*!}"
99

#뒤에는 다음과 같은 패턴이 따릅니다.가장 짧은 접두사이 패턴과 일치하는 항목이 삭제됩니다.

$ input='string/more!99,string/more!98,string/more!97'
$ first=${input%%,*}
$ echo "${first#*!}"
99

%%뒤에는 다음과 같은 패턴이 따릅니다.가장 긴 접미사일치하는 패턴이 삭제됩니다.


${var#pattern)-- 가장 짧은 일치 접두사를 제거합니다.
${var##pattern)-- 일치하는 가장 긴 접두사를 제거합니다.
${var%pattern)-- 일치하는 가장 짧은 접미사를 제거합니다.
${var%%pattern)-- 일치하는 가장 긴 접미사를 제거합니다.

답변4

sed.GNU를 사용 sed하고 확장 정규식을 활성화 할 수도 있습니다 .

sed -E 's/^[^!]*!([0-9]+).*$/\1/'

또는 - 더 휴대성이 뛰어납니다.

sed 's/^[^!]*!\([0-9]\{1,\}\).*$/\1/p'

!이는 "첫 번째 숫자 앞의 모든 항목 , 그 뒤에 하나 이상의 숫자, 그 뒤에 줄 끝까지의 모든 유형의 문자가 오는 " 패턴과 일치 하고 전체 줄을 "하나 이상의 숫자" 부분으로만 바꿉니다.

~> echo 'string/more!99,string/more!98,string/more!97' | sed -E 's/^[^!]*!([0-9]+).*$/\1/'
99

일치하지 않는 행이 있는 경우 다음을 사용하여 이를 억제할 수 있습니다.

sed -nE 's/^[^!]*!([0-9]+).*$/\1/p'

대신에. 기본적으로 이는 아무것도 출력하지 않으며 일치하는 패턴이 발견된 경우에만 출력을 인쇄합니다.

관련 정보