정규식을 사용하여 행의 N번째 필드 문자열을 일치시키는 방법은 무엇입니까?

정규식을 사용하여 행의 N번째 필드 문자열을 일치시키는 방법은 무엇입니까?

나는 15번째 단어의 모든 줄에서 문자열 "RAV"를 일치시키려고 노력하고 있습니다. 각 단어는 "|"(파이프)로 구분됩니다. 행에 이 문자열이 있는지 비교해야 합니다. 그렇다면 다음 단계로 넘어가겠습니다.

나는 이것을 시도하고있다

((((?:[^|]*\|){17}(.*?)\|)+\|[^|]*$)|[^|]+(?=(\,\H\,))|(^([0-9]){4})|(([RAV]){3}))

하지만 첫 번째, 두 번째 또는 다른 필드가 "RAV"인 경우에도 이는 일치합니다. 필드 15에서 정확히 일치하는 항목이 필요합니다.

답변1

반드시 정규식을 사용할 필요는 없습니다.

그리고 awk:

awk -F '|' '$15 == "RAV" { print }' myfile

myfile이렇게 하면 15번째 |구분 필드가 정확히 string 인 파일의 모든 줄이 인쇄됩니다 RAV. 이는 정규식 일치보다는 문자열 비교를 사용합니다.

RAV15번째 필드의 어느 위치에서나 부분 문자열로 일치시키 려면 다음을 사용하십시오.

awk -F '|' '$15 ~ /RAV/ { print }' myfile

이는 RAV정규식을 확장하고 이를 15번째 구분 필드의 데이터와 일치시키는 데 사용됩니다 |. 일치하는 것이 있으면 현재 줄을 인쇄합니다.

이것이 호출하기 어려운 언어 awk(예: 쉘 스크립트 이외의 언어)로 작성된 일부 스크립트 또는 프로그램의 일부인 경우 구분 기호에서 문자열을 분할 |하고 15번째 요소를 선택하여 비교하십시오.

awk의사코드 언어 로 사용되면 다음과 같이 보일 수 있습니다.

nf = split($0, a, "|")
if (nf < 15)
    print "Not enough fields!" >"/dev/stderr"
else {
    if (a[15] == "RAV") print
}

또는 Perl에서는(이번에는 오류를 확인하지 않음)

my @a = split /\|/, $string;
if ($a[15] eq "RAV") {
    print $string
}

위의 각 변형(초기 awk명령 포함) 에서 는 print15번째 필드가 일치한다고 판단한 후 데이터에 대해 수행해야 하는 모든 작업을 나타냅니다 RAV.

답변2

grep -E '^([^|]*\|){14}[^|]*RAV' infile
  • (...)조별 예선이라고 불렀습니다.
  • {N}이를 고정 간격 수량자라고 합니다.
  • (...){N}조별 예선에서 N번 대결하세요.

답변3

정규식을 사용할 수는 있지만, 이런. 예. 그것에 대해. awk비슷한 방식으로 필드 분할을 수행 할 수도 있습니다 . 이유를 알 수 있나요?

$ cat input
ok|x|x|x|x|x|x|x|x|x|x|x|x|x|RAV
ok|x|x|x|x|x|x|x|x|x|x|x|x|x|RAV|bar
bad|x|x|x|x|x|x|x|x|x|x|x|x|x|NOPE
bad|x|x|x|x|x|x|x|x|x|x|x|x|x|NOPE|bar
$ sed -E -n '/^[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|RAV(\||$)/p' input
ok|x|x|x|x|x|x|x|x|x|x|x|x|x|RAV
ok|x|x|x|x|x|x|x|x|x|x|x|x|x|RAV|bar

[^|]*\|양식은 기본적으로 "필드 일치"를 의미합니다. 필드는 절대로 이스케이프될 수 없으며 15번째 필드를 처리하기 전에 14번 |반복됩니다(저는 한 번 vi입력했습니다 ). 14i매우 역겹고 유지 관리가 어렵습니다.

대신 PS를 사용하세요 awk.

답변4

Raku(이전 Perl_6) 사용

raku -ne '.put if / ^ [ .+ ]**14 % "|" RAV /;' 

위의 답변은 훌륭하지만 Raku는 이러한 유형의 문제를 크게 단순화하는 새롭고 아름답고 수정된 수량자를 %제공 합니다. %%문서에 따르면:%"쉼표로 구분된 값과 같은 항목을 더 쉽게 일치시키려면 위 수량자에 수정자를 추가하여 각 일치 항목 사이에 나타나야 하는 구분 기호를 지정할 수 있습니다."수정된 수량자는 %%후행 쉼표와 같은 후행 구분 기호를 허용합니다.

원자가 포함된 위의 코드에서는 [ .+ ]각 열에 하나 이상의 문자(공백 포함)가 있어야 합니다. 이는 [ \S+ ](공백이 아닌 하나 이상의 문자) 또는 심지어 [ .* ](0개 이상의 문자) 로 변경될 수 있습니다 .

또한 다른 답변과 마찬가지로 |세로 막대로 분할하여 이 문제를 해결할 수 있습니다.

raku -ne '.put if .split("|")[14] eq "RAV" // next;'  

#OR

raku -ne '.split("|")[14] eq "RAV" ?? $_.put !! next;'  

입력 예(@thrig 덕분에):

ok|x|x|x|x|x|x|x|x|x|x|x|x|x|RAV
ok|x|x|x|x|x|x|x|x|x|x|x|x|x|RAV|bar
bad|x|x|x|x|x|x|x|x|x|x|x|x|x|NOPE
bad|x|x|x|x|x|x|x|x|x|x|x|x|x|NOPE|bar

예제 출력:

ok|x|x|x|x|x|x|x|x|x|x|x|x|x|RAV
ok|x|x|x|x|x|x|x|x|x|x|x|x|x|RAV|bar

https://raku.org

관련 정보