sed, awk 또는 gawk를 사용하여 일치하는 항목 만 인쇄하는 방법은 무엇입니까?
sed, awk 또는 gawk를 사용하여 검색 및 바꾸기와 같은 작업을 수행하는 방법에 대한 많은 예제와 매뉴얼 페이지를 봅니다.
하지만 제 경우에는 특정 값을 추출하기 위해 텍스트 파일에 대해 실행하려는 정규식이 있습니다. 검색 및 바꾸기를 원하지 않습니다. 이것은 bash에서 호출됩니다. 예를 들어 보겠습니다.
정규 표현식의 예 :
.*abc([0-9]+)xyz.*
입력 파일 예 :
a
b
c
abc12345xyz
a
b
c
간단하게 들리지만 sed / awk / gawk를 올바르게 호출하는 방법을 알 수 없습니다. 내가 원하는 것은 bash 스크립트 내에서 다음과 같습니다.
myvalue=$( sed <...something...> input.txt )
내가 시도한 것은 다음과 같습니다.
sed -e 's/.*([0-9]).*/\\1/g' example.txt # extracts the entire input file
sed -n 's/.*([0-9]).*/\\1/g' example.txt # extracts nothing
내 sed
(Mac OS X)가 +
. *
대신 시도 하고 p
인쇄 일치 태그를 추가했습니다 .
sed -n 's/^.*abc\([0-9]*\)xyz.*$/\1/p' example.txt
없이 하나 이상의 숫자를 일치 시키 +
려면 다음을 사용합니다.
sed -n 's/^.*abc\([0-9][0-9]*\)xyz.*$/\1/p' example.txt
sed를 사용하여이 작업을 수행 할 수 있습니다.
sed -rn 's/.*abc([0-9]+)xyz.*/\1/gp'
-n
결과 라인을 인쇄하지 마십시오-r
이렇게하면 캡처 그룹 괄호를 탈출 할 수 없습니다()
.\1
포획 그룹 경기/g
글로벌 경기/p
결과를 인쇄
이 작업을 더 쉽게 만들어주는 도구 를 직접 작성했습니다.
rip 'abc(\d+)xyz' '$1'
나는 perl
이것을 더 쉽게 만들기 위해 사용 합니다. 예 :
perl -ne 'print $1 if /.*abc([0-9]+)xyz.*/'
이것은 Perl을 실행하고이 -n
옵션은 Perl이 STDIN에서 한 번에 한 줄씩 읽고 코드를 실행하도록 지시합니다. 이 -e
옵션은 실행할 명령을 지정합니다.
이 명령어는 read 행에서 regexp를 실행하고 일치하는 경우 첫 번째 중괄호 ( $1
) 세트의 내용을 인쇄합니다 .
당신은 또한 끝에 여러 파일 이름을 할 수 있습니다. 예 :
perl -ne 'print $1 if /.*abc([0-9]+)xyz.*/' example1.txt example2.txt
버전 경우 grep
지원을 당신이 사용할 수있는 -o
인쇄 옵션을 단지 당신의 정규 표현식 일치하는 모든 라인의 일부를.
그렇지 않다면 여기에 sed
내가 생각 해낼 수 있는 최선의 방법이 있습니다 .
sed -e '/[0-9]/!d' -e 's/^[^0-9]*//' -e 's/[^0-9]*$//'
... 숫자없이 삭제 / 건너 뛰고 나머지 행의 경우 모든 선행 및 후행 숫자가 아닌 문자를 제거합니다. (나는 당신의 의도가 하나를 포함하는 각 줄에서 숫자를 추출하는 것이라고 추측하고 있습니다).
다음과 같은 문제 :
sed -e 's/.*\([0-9]*\).*/&/'
.... 또는
sed -e 's/.*\([0-9]*\).*/\1/'
... is that sed
only supports "greedy" match ... so the first .* will match the rest of the line. Unless we can use a negated character class to achieve a non-greedy match ... or a version of sed
with Perl-compatible or other extensions to its regexes, we can't extract a precise pattern match from with the pattern space (a line).
You can use awk
with match()
to access the captured group:
$ awk 'match($0, /abc([0-9]+)xyz/, matches) {print matches[1]}' file
12345
This tries to match the pattern abc[0-9]+xyz
. If it does so, it stores its slices in the array matches
, whose first item is the block [0-9]+
. Since match()
returns the character position, or index, of where that substring begins (1, if it starts at the beginning of string), it triggers the print
action.
With grep
you can use a look-behind and look-ahead:
$ grep -oP '(?<=abc)[0-9]+(?=xyz)' file
12345
$ grep -oP 'abc\K[0-9]+(?=xyz)' file
12345
This checks the pattern [0-9]+
when it occurs within abc
and xyz
and just prints the digits.
perl is the cleanest syntax, but if you don't have perl (not always there, I understand), then the only way to use gawk and components of a regex is to use the gensub feature.
gawk '/abc[0-9]+xyz/ { print gensub(/.*([0-9]+).*/,"\\1","g"); }' < file
output of the sample input file will be
12345
Note: gensub replaces the entire regex (between the //), so you need to put the .* before and after the ([0-9]+) to get rid of text before and after the number in the substitution.
If you want to select lines then strip out the bits you don't want:
egrep 'abc[0-9]+xyz' inputFile | sed -e 's/^.*abc//' -e 's/xyz.*$//'
It basically selects the lines you want with egrep
and then uses sed
to strip off the bits before and after the number.
You can see this in action here:
pax> echo 'a
b
c
abc12345xyz
a
b
c' | egrep 'abc[0-9]+xyz' | sed -e 's/^.*abc//' -e 's/xyz.*$//'
12345
pax>
Update: obviously if you actual situation is more complex, the REs will need to me modified. For example if you always had a single number buried within zero or more non-numerics at the start and end:
egrep '[^0-9]*[0-9]+[^0-9]*$' inputFile | sed -e 's/^[^0-9]*//' -e 's/[^0-9]*$//'
you can do it with the shell
while read -r line
do
case "$line" in
*abc*[0-9]*xyz* )
t="${line##abc}"
echo "num is ${t%%xyz}";;
esac
done <"file"
For awk. I would use the following script:
/.*abc([0-9]+)xyz.*/ {
print $0;
next;
}
{
/* default, do nothing */
}
gawk '/.*abc([0-9]+)xyz.*/' file
참고URL : https://stackoverflow.com/questions/1733692/how-to-use-sed-awk-or-gawk-to-print-only-what-is-matched
'developer tip' 카테고리의 다른 글
CSS : x 축에 고정 된 위치이지만 y가 아님? (0) | 2020.08.24 |
---|---|
이 이상한 결장 행동은 무엇을하고 있습니까? (0) | 2020.08.24 |
log4net에서 publickeytoken을 계속 변경하려면 어떻게해야하나요? (0) | 2020.08.24 |
Semaphore와 SemaphoreSlim 중에서 어떻게 선택합니까? (0) | 2020.08.24 |
C #에서 const 매개 변수가 허용되지 않는 이유는 무엇입니까? (0) | 2020.08.24 |