가정:
이것이 내가 표시하는 유일한 텍스트입니다. 나머지 텍스트에는 [표시되지 않음] 더 많은 데이터가 있는데 이것이 문제입니다. 텍스트는 약간 깨끗하고 공백, 탭, 유니코드로 가득 차 있고 깨끗하지 않으며 다음과 같아야 합니다 [내 필요]. 따라서 이 정확한 텍스트를 복사하여 붙여넣는 것은 작동하지 않습니다 [마크업 형식]:
나는 가지고있다일부다음과 같은 텍스트:
*** *
more text with spaces and tabs
*****
1
Something here and else, 2000 edf, 60 pop
Usd324.32 2 Usd534.22
2
21st New tetx that will like to select with pattern, 334 pop
Usd162.14
*** *
more text with spaces and tabs, unicode
*****
나는 다음과 같은 명시적인 텍스트를 얻으려고 합니다.
1 Something here and else, 2000 edf, 60 pop Usd324.32
newline
및 때문에 whitespace
다음 명령은 다음만 가져옵니다 1
.
grep -E '1\s.+'
또한 저는 새로운 연결을 사용하여 이 작업을 수행하려고 했습니다.
grep -E '1\s|[A-Z].+'
하지만 작동하지 않습니다. grep
텍스트의 다른 부분에서 유사한 패턴을 선택하기 시작했습니다.
awk '{$1=$1}1' #done already
tr -s "\t\r\n\v" #done already
tr -d "\t\b\r" #done already
어떻게 잡을 수 있나요?
- 1개를 잡아라
newline
- 그런 다음 두 번째 줄 전체를 잡아1
newline
- 번호 잡고
$Usd324.34
삭제해Usd
답변1
pcregrep
Ultiline 모드와 캡처 그룹의 내용을 출력하는 기능이 있습니다 M
.o
$ pcregrep -Mo1 -o2 -o3 --om-separator ' ' '^(1)\n(.*)\n\h*Usd(\H+)' file
1 Something here and else, 2000 edf, 60 pop 324.32
답변2
- "1"과 선택적 공백만 포함하는 줄로 시작하는 세 줄을 연결하고 수정하려면 다음을 수행하세요.
$ perl -0777ne '/^1\s+(.*?)\h*\n\h*Usd(\H+)/imsg && printf "1 %s %s\n", $1, $2' input.txt
1 Something here and else, 2000 edf, 60 pop 324.32
이 -0777
옵션은 Perl이 한 번에 한 줄씩 읽는 대신 전체 파일을 한 번에 읽도록 지시합니다. -n
유사한 방식으로 입력을 처리하도록 지시합니다 sed -n
. -e
Perl에게 다음 인수가 스크립트임을 알려줍니다.
정규식이 텍스트와 일치하면 RE 캡처 그룹에서 캡처한 텍스트를 원하는 형식으로 인쇄합니다.
"선택적 후행 공백"을 일치시키는 것은 귀하의 질문에서 복사하여 붙여넣은 예제 파일에 여러 줄에 후행 공백 문자가 있다는 사실을 처리하는 것입니다. 이것이 원본 파일에 있었는지 아니면 질문에 붙여 넣은 인공물인지는 알 수 없습니다. 중요하지 않습니다. 스크립트는 후행 공백이 있는지 여부에 관계없이 동일한 방식으로 작동합니다.
- 숫자와 선택적 공백만 포함하는 줄로 시작하는 세 줄의 그룹을 결합하고 수정하려면 다음을 수행하세요.
$ perl -n -e 'if (/^\d+\s*$/) {
chomp; $_ .= " " . <>;
chomp; $_ .= " " . <>;
s/\s{2,}/ /g;
s/Usd(\H+).*/$1/i;
print
}' input.txt
1 Something here and else, 2000 edf, 60 pop 324.32
2 21st New tetx that will like to select with pattern, 334 pop 162.14
줄에 선택적 후행 공백이 있는 숫자만 포함될 때마다 다음 두 줄을 가져와 현재 줄에 추가한 다음 수정하고 인쇄합니다.
chomp
각 줄 끝에서 개행 문자를 제거 하고 <>
다음 입력 줄을 읽습니다. 다음 두 줄을 가져와 추가하기 위해 두 번 실행됩니다. 그런 다음 연결된 줄을 두 가지 작업으로 수정합니다 s///
(첫 번째 작업은 두 개 이상의 공백 문자를 단일 공백으로 줄이고, 두 번째 작업은 첫 번째 "Usd\H+" 뒤의 줄에서 모든 항목을 제거하고 리터럴 문자열 "Usd"도 제거합니다. 인쇄하기 전에 마지막 작업이 완료됩니다(대소문자 구분 안 함).
\h
수평 공백 문자와 일치하는 Perl 정규식입니다. \H
반대입니다. 어떤 것과도 일치합니다.아니요수평 공백.
- 이 두 가지 perl one-liner는 원본 샘플 데이터와 편집된 질문의 업데이트된 예제에서 작동하고 동일한 출력을 생성합니다.
답변3
다음과 같이 사용할 수 있습니다 awk
.
$ awk 'BEGIN {count = 0; ORS=" "} /^1$/ {found = 1; print; next; count++} found && count < 1 {count++; print; next} count == 1 {print $1; exit} END {printf "\n"}' < FILE
1 Something here and else, 2000 edf, 60 pop 324.32
또는 다음을 사용하십시오 getline()
.
awk 'BEGIN {ORS=" "} /^1$/ {getline; print; getline; print $1} END {printf "\n"}' < FILE
답변4
sed
이 직업에도 적합합니다:
sed -n '/^1 $/{h;n;H;n;s/^ *\([0-9.]*\).*/ \1/;H;g;s/\n//g;p}' sample