Linux Bash에서 대괄호 안의 복잡한 문자열 추출

Linux Bash에서 대괄호 안의 복잡한 문자열 추출

Linux bash 도구를 통해 다음 문자열을 추출하고 싶습니다.

XXAAGGHH (XXXXX) ERRTYTUUUI
AAAAAAAA ( %%))XX) $@@$&%^&&
AADDDDD$ (.SD F@* @) *$%^^&^&&&
AA^@%%^^ ()[))DS((]) RTTYUU

추출된 해상도는 다음과 같아야 합니다.

XXXXX
  %%))XX
.SD F@* @
)[))DS((]

불행히도 문자열 길이가 고정되어 있지 않기 때문에 substr을 사용할 수 없습니다. 괄호 안에 괄호(균형이 맞지 않을 수 있음), 공백 또는 탭이 있을 수 있습니다(실제로 이는 UTF-8 횡설수설이지만 로컬 시스템은 ASCII만 표시할 수 있습니다.)

내가 사용하는 패턴은 "(": 공백 + 왼쪽 대괄호는 왼쪽 경계를 나타냅니다. ")": 공백 + 오른쪽 대괄호는 오른쪽 경계를 나타냅니다.

awk, sed, grep을 시도했지만 실패했습니다.

힌트를 주실 수 있나요? 감사해요.

답변1

sed유일한 해결책:

sed 's/.* (\(.*\)) .*/\1/g'

예:

sed 's/.* (\(.*\)) .*/\1/g' myInput.txt 
XXXXX
 %%))XX
.SD F@* @
)[))DS((]

답변2

grep -Eo '\(.+\)' input | sed 's/^.//; s/.$//'

답변3

패턴을 찾기 위해 단순히 예제를 반복하는 것이 솔루션을 개발하는 쉬운 방법이라는 점에 유의하십시오. 제가 일반적으로 하는 작업입니다. 또한 이를 통해 다른 사람들이 파일을 생성하지 않고도 콘솔에서 시도해 볼 수 있습니다.

Gawk의 유일한 솔루션:

echo 'XXAAGGHH (XXXXX) ERRTYTUUUI
AAAAAAAA ( %%))XX) $@@$&%^&&
AADDDDD$ (.SD F@* @) *$%^^&^&&&
AA^@%%^^ ()[))DS((]) RTTYUU' | gawk '{r=gensub(/^[^(]*\((.*)\)[^)]*$/,"\\1","g",$0);print r}'
XXXXX
 %%))XX
.SD F@* @
)[))DS((]

awk 전용 솔루션:

echo 'XXAAGGHH (XXXXX) ERRTYTUUUI
AAAAAAAA ( %%))XX) $@@$&%^&&
AADDDDD$ (.SD F@* @) *$%^^&^&&&
AA^@%%^^ ()[))DS((]) RTTYUU' | awk '{gsub(/^[^(]*\(|\)[^)]*$/,"",$0);print $0}'
XXXXX
 %%))XX
.SD F@* @
)[))DS((]

sed 전용 솔루션:

echo 'XXAAGGHH (XXXXX) ERRTYTUUUI
AAAAAAAA ( %%))XX) $@@$&%^&&
AADDDDD$ (.SD F@* @) *$%^^&^&&&
AA^@%%^^ ()[))DS((]) RTTYUU' | sed -r 's/^[^(]*\(|\)[^)]*$//g'
XXXXX
 %%))XX
.SD F@* @
)[))DS((]

또는 파일의 경우:

gawk '{r=gensub(/^[^(]*\((.*)\)[^)]*$/,"\\1","g",$0);print r}' input_file
# OR
awk '{gsub(/^[^(]*\(|\)[^)]*$/,"",$0);print $0}' input_file
# OR
sed -r 's/^[^(]*\(|\)[^)]*$//g'  input_file
# all output:
XXXXX
 %%))XX
.SD F@* @
)[))DS((] 

이런 식으로 배우려고 노력하는 것은 매우 나쁜 생각이지만, 스스로 알아내기 위해 정규 표현식에 머리를 부딪히는 것을 대체할 수 있는 방법은 없습니다. 그렇지 않으면 실제로 배울 수 없습니다. 제 생각에는 프로그래밍에서 정규 표현식보다 더 가치 있는 장기 학습은 없습니다.

규칙은 간단합니다. 줄을 끝내는 a가 아닌 모든 항목(줄을 시작한 다음 첫 번째 항목(및 무시하거나 삭제한 다음 a가 아닌 모든 항목과 마지막 항목)을 더함)을 가져오고 이를 무시하거나 삭제합니다. 주어진 대답에는 이 경우 두 가지 옵션이 있다는 것을 알 수 있습니다. 줄의 시작과 끝을 잘라내어 원하는 결과를 얻거나 줄의 시작과 끝을 무시하여 원하는 결과를 얻은 다음 결과를 인쇄합니다. 결과.

일단 패턴이 있으면 이를 구현하는 데 어떤 언어나 도구를 사용하는지는 그다지 중요하지 않습니다.

관련 정보