다음을 포함하는 로그 파일에서 일부 정보를 추출하고 싶습니다.
...
Running ep. 0
...
...
Initial position for this ep is 7.338690864048985,28.51815509409351,11.795143979909135
...
...
...
Running ep. 1
...
...
Initial position for this ep is 10.599326804010953,7.514871863851674,14.843070346933654
...
...
이제 일부 데이터를 추출할 수 있는 bash 코드가 생겼습니다.
cat screen2.dat|grep -oP 'Running ep. \K([0-9]+)|(?<=for this ep is )[+-]?[0-9]+([.][0-9]+)?'|paste -d' ' - -
그러나 출력은 "Running ep" 이후의 숫자일 뿐입니다. "이 ep의 초기 위치는" 다음의 첫 번째 숫자입니다.
0 7.338690864048985
1 10.599326804010953
.
.
.
나는 다음과 같은 것을 기대하고 있었다
0 7.338690864048985 28.51815509409351 11.795143979909135
1 10.599326804010953 7.514871863851674 14.843070346933654
.
.
.
답변1
표현을 너무 과하게 지정하신 것 같네요. substring 뒤에 단일 float만 일치합니다 for this ep is
. 나머지 줄을 원하면 다음과 같은 것을 사용하십시오
grep -oP 'Running ep\. \K(.*)|for this ep is \K(.*)' screen2.dat |
paste -d ' ' - -
표준을 사용하여 sed
다음을 작성할 수 있습니다.
sed -n -e 's/^Running ep\. //p' -e 's/.*for this ep is //p' screen2.dat |
paste -d ' ' - -
선의 불필요한 부분을 잘라냅니다(제거할 항목이 없는 것으로 교체).
awk
같은 방법으로 사용 하셔도 되고 ,
awk '/^Running ep\. / || /for this ep is / { print $NF }' screen2.dat |
paste -d ' ' - -
아니면 한번에 모든 것을 포맷하고,
awk '/^Running ep\. / { ep = $NF } /for this ep is / { print ep, $NF }' screen2.dat
답변2
귀하의 코드는 [+-]?[0-9]+([.][0-9]+)?
점 뒤에 선택적 숫자가 있는 단일 숫자와 일치합니다. 3개를 원하시면 이렇게 말씀하세요.([+-]?[0-9]+([.][0-9]+)?,?){3}
하지만 당신이 정말로 원하는 것은 sed
단지 스크립트에 불과합니다:
sed -e '/Running ep. /{s///;h;}' -e '/.*for this ep is /!d;s///;H;x;s/[\n,]/ /g' screen2.dat
/Running ep. /{...}
{}
일치하는 줄 안에서만 모든 것을 실행하는 것입니다.Running ep.
- 이러한 행의 경우
s///
이전에 일치한 부분을 삭제하고 행을h
이전 공간 으로 이동합니다. /.*for this ep is /!d
No!
다른 패턴과 일치하지 않는 ( )가 있는 모든 행을d
선택할 수 있으며,- 나머지는
s///
패턴을 다시 제거하고 행의 나머지 부분은 모두 숫자로 남겨 두십시오. H
ep 번호를 얻을 수 있는 예약된 공간에 이 나머지를 추가합니다.x
버퍼를 교환하여 예약된 공간에서 수집한 두 부분이 이제 패턴 공간에 있게 됩니다.s/[\n,]/ /g
포함된 줄바꿈과 모든 쉼표를 공백으로 바꾸기
답변3
와 궁극 pcregrep
의 M
모드:
$ <input pcregrep -M -o{1..4} --om-separator=' ' \
'(?sm)^Running ep\. (\d+)$.*?^Initial position for this ep is ([+-]?\d+(?:\.\d+)?),((?2)),((?2))$'
0 7.338690864048985 28.51815509409351 11.795143979909135
1 10.599326804010953 7.514871863851674 14.843070346933654
그러나 Initial...
특정 항목이 누락된 경우 다른 항목과 일치하게 되며Running ep...
주어진 값 집합 앞에 잘못된 ep 번호가 표시될 수 있습니다..*?
Running ep...
아마도 gawk
다음과 같이 하는 것이 더 나을 것입니다:
<input gawk -v 'FPAT=[+-]?[0-9]+([.][0-9]+)?' '
/^Running ep/ && NF == 1 {ep = $1; next}
/^Initial position for this ep is/ && ep != "" && NF == 3 {
print ep, $1, $2, $3
ep = "" # omit if there can be more than one "Initial position"
# per ep.
}'
여기서 FPAT
필드는 정규식(숫자)과 일치하는 문자열로 정의되며 출력 한 줄만 인쇄합니다.초기 위치좋아, 해당하는 것이 있다면러닝 EP그 줄은 이전에 본 적이 있습니다.
답변4
모든 Unix 시스템의 모든 쉘에서 awk를 사용하십시오.
$ awk '/Running ep/{ep=$NF} /Initial position/{print ep, $NF}' file
0 7.338690864048985,28.51815509409351,11.795143979909135
1 10.599326804010953,7.514871863851674,14.843070346933654
해당 쉼표를 공백으로 바꾸려면 다음을 수행하십시오.
$ awk '/Running ep/{ep=$NF} /Initial position/{gsub(/,/," ",$NF); print ep, $NF}' file
0 7.338690864048985 28.51815509409351 11.795143979909135
1 10.599326804010953 7.514871863851674 14.843070346933654