다음 내용이 포함된 file2.txt 파일을 고려해 보세요.
P 89 24 -1.5388040474568784e+01 7.4421775186012660e+00 -1.3143195543234219e+03 1.3168884860257754e+03 8.0419002445999993e+01 44 0 0 -97 0
P 122 -4 -1.4869334602986523e+01 5.7316939411954255e+00 -1.3144161801429666e+03 1.3169704096915282e+03 8.0419002445999993e+01 44 0 0 -370 0
P 493 -24 -1.4690576431881317e+01 7.3848907323212831e+00 -1.3144620647251766e+03 1.3170224315489374e+03 8.0419002445999993e+01 62 0 0 -499 0
E 3 -1 -1.0000000000000000e+00 -1.0000000000000000e+00 -1.0000000000000000e+00 9999 0 970 1 2 0 7 1.7003962000000002e+05 8.5019810000000018e-01 8.5019810000000018e-01 8.5019810000000018e-01 3.0000000000000000e+01 3.8153441026312507e+01 1.0000000000000000e+11
E 4 -1 -1.0000000000000000e+00 -1.0000000000000000e+00 -1.0000000000000000e+00 9999 0 818 1 2 0 7 1.7003962000000002e+05 8.5019810000000018e-01 8.5019810000000018e-01 8.5019810000000018e-01 3.0000000000000000e+01 3.2509364886711985e+01 1.0000000000000000e+11
P 5 2 0 0 3.7531787088999999e+02 3.8383684055052936e+02 8.0419002445999993e+01 22 0 0 -6 0
P 8 24 7.0195398693654170e+00 3.1543502387874696e+01 5.5989200759599044e+01 1.0318077843755555e+02 8.0419002445999993e+01 44 0 0 -50 0
P 67 28 5.8271676589304882e+00 3.3476871962084061e+01 5.6723118833601163e+01 1.0411236719963519e+02 8.0419002445999993e+01 44 0 0 -168 0
P 219 13 6.0328453988772415e+00 3.3531592253635168e+01 5.6777179460595200e+01 1.0417114266715717e+02 8.0419002445999993e+01 44 0 0 -329 0
P 444 -24 6.4646967953734418e+00 3.4909545978243479e+01 5.7879920796889749e+01 1.0525098522544691e+02 8.0419002445999993e+01 62 0 0 -452 0
E 5 -1 -1.0000000000000000e+00 -1.0000000000000000e+00 -1.0000000000000000e+00 9999 0 598 1 2 0 7 1.7003962000000002e+05 0 0 8.5019810000000018e-01 3.0000000000000000e+01 6.8997318544430456e+01 1.0000000000000000e+11
나는 단지 문자열 P ... 24 ...
또는 을 추출하고 싶습니다 P ... -24 ...
. 이것이 제가 한 일입니다:
cat file2.txt | grep -E '(P [0-9]+ 24 | P [0-9] + -24 |P [0-9][0-9]+ 24 | P [0-9][0-9] + -24 |P [0-9][0-9][0-9] + 24 | P [0-9][0-9][0-9] + -24 |P [0-9][0-9][0-9][0-9]+ 24 | P [0-9][0-9][0-9][0-9] + -24 )' &> file3.txt
그러나 생성된 file3.txt에는 문자열만 포함되어 있습니다 P ... 24
. 내가 뭘 잘못하고 있는지 말해 줄 수 있나요?
답변1
.... 내가 뭘 잘못했나요? ...더 복잡하게 만드는 것 외에도... 모든 경우 -24
와 다른 경우에 문자열에 없는 여러 공백과 선행 공백을 일치시키려고 합니다 ...
P [0-9]+ 24 |
알겠습니다 P
. 일련의 숫자
[0-9]+
와 공백
24
을 차례로 입력하세요.
| P [0-9] + -24 |
여기의 숫자 앞과 뒤에는 하나 이상의 공백이 있고, 그 뒤에는 추가 공백으로 인해 일치할 수 없는 또 다른 공백이 옵니다.
P
+
|P [0-9][0-9]+ 24 |
다시 한 번 잘 작동하지만 모든 일치 항목이 이미 첫 번째 패턴에서 캡처되었으므로 중복됩니다.
| P [0-9][0-9] + -24 |
추가 공백, 위와 동일 -24
... 일치하지 않음
|P [0-9][0-9][0-9] + 24 |
예전에 여유공간이 있었 어서 다시 2개 이상 +
찾아보게 되더라구요 ...
| P [0-9][0-9][0-9] + -24 |
the 앞에는 선행 공백이 있고, 다시 P
2개 이상의 공백이 앞에 옵니다.-24
|P [0-9][0-9][0-9][0-9]+ 24 |
훌륭하지만 중복됨
| P [0-9][0-9][0-9][0-9] + -24
the 앞에는 선행 공백이 있고, 다시 P
2개 이상의 공백이 앞에 옵니다.-24
@gillesquenot은 더 우아한 솔루션을 제공하지만 추가 공간을 잃어도 솔루션이 "작동"합니다...
grep -E '(P [0-9]+ 24 |P [0-9]+ -24 |P [0-9][0-9]+ 24 |P [0-9][0-9]+ -24 |P [0-9][0-9][0-9] + 24 |P [0-9][0-9][0-9]+ -24 |P [0-9][0-9][0-9][0-9]+ 24 |P [0-9][0-9][0-9][0-9]+ -24 )'
여러 공간을 사용할 수 있는 경우
grep -E '^P +[0-9]+ +-?24'
편집하다
이것문자열에서 일치하는 내용과 위치를 확인하는 데 유용한 리소스입니다.
답변2
미션 같은데앗! 이것은DSL1: 이것이 바로 awk
가는 길입니다.
간단하고 재사용이 가능하며 효율적이고 빠릅니다.
아니요정규식:
awk '$1 == "P" && ($3 == "-24" || $3 == "24")' file2.txt
또는 사용정규식:
awk '$1 == "P" && $3 ~ /^-?24$/' file2.txt
여기서 정규 표현식에서 /^-?24$/
대시는 선택 사항이므로 이 짧은 문자를 사용할 수 있습니다.정규식.
정규식 일치는 다음과 같습니다.
마디 | 설명하다 |
---|---|
^ |
문자열의 시작 |
-? |
'-'(선택 사항(최대한 많이 일치)) |
24 |
'스물넷' |
$ |
선택적 \n 앞과 문자열 끝 |
1 가장 유명한 채팅에 질문을 해보세요
Q: DSL은 개발자에게 무엇을 의미합니까?
DSL(도메인 특정 언어)는 특정 작업을 보다 쉽게 코딩할 수 있도록 설계된 컴퓨터 언어입니다. 특정 애플리케이션 도메인에 맞게 조정되어 개발자가 빠르고 효율적으로 코드를 작성할 수 있습니다. DSL의 일반적인 용도에는 데이터베이스 쿼리, 텍스트 처리 및 과학 시뮬레이션이 포함됩니다. DSL을 사용하면 개발자는 특정 목적을 위한 애플리케이션을 신속하게 구축하여 보다 직관적인 프로그래밍 접근 방식을 제공하고 구문에 대한 의존도를 줄일 수 있습니다.
답변3
정규식을 조금 단순화해 보겠습니다.
grep -E '^P [0-9]+ -?24\b' file2.txt
원하지 않는 복잡성과 가독성 외에도 정규식의 주요 문제점은 잘못된 공백을 추가로 사용한다는 것입니다.
불필요한:
cat | grep
를 사용하세요 .고양이의 쓸모없는 사용multiple|regex
여기에서 사용하세요
입력에 더 많은 공간을 확보할 수 있다고 생각되면 다음 중 하나를 사용할 수 있습니다.
+
[[:space:]]+
(POSIX
문자 클래스)\s+
-P
일명PCRE
스위치가 필요하다grep
정규식 일치는 다음과 같습니다.
마디 | 설명하다 |
---|---|
^ |
선 기준점의 시작점 |
P |
'P'+스페이스 |
[0-9]+ |
모든 문자: "0" ~ "9"(1회 이상(최대한 많이 일치)) |
|
공간 |
-? |
'-'(선택 사항(최대한 많이 일치)) |
24 |
'스물넷' |
\b |
단어 경계 |
답변4
글쎄, 값이 24일 수 있는 하나의 필드에만 의존하고 있는 것입니다. 이는 잘못된 설계처럼 보입니다. 예를 들어 cut
추가 분석을 위해 해당 파일에서 첫 번째 및 세 번째 열을 추출할 수 있는 도구가 많이 있습니다 .
하지만 솔직하게 말하자면 이는 sed
또는 와 같은 cut
문자열 엔진 이 아니라 표 형식의 숫자 데이터를 처리하는 도구의 작업입니다 grep
.
솔직히 말해서, 몇 줄의 Python(또는 Perl 또는... 원하는 프로그래밍 언어)이 이 문제를 해결할 것입니다. 어쨌든 여기서 결과를 프로그래밍 방식으로 처리할 것이라고 100% 확신합니다. 시작 언어부터.
간단히 설명하면 다음과 같습니다.
#!/usr/bin/env python3
import sys
with open(sys.argv[1], "r", encoding="ascii") as inputfile:
linecounter = 0
for line in inputfile:
linecounter += 1
try:
if not line.startswith("P "):
continue # skip this line alltogether
thirdpos = int(line.split(" ")[2])
if not (thirdpos == 24 or thirdpos == -24):
continue
print(line) # or actually, do something useful with the line
except Exception as e:
print("Exception occurred on line {linecounter}, '{line}':\n{e}", sys.stderr)
텍스트 파일에서 chmod 755 thatfile
, 를 실행한 다음 /path/to/thatfile /path/to/input_file
.