나는 15번째 단어의 모든 줄에서 문자열 "RAV"를 일치시키려고 노력하고 있습니다. 각 단어는 "|"(파이프)로 구분됩니다. 행에 이 문자열이 있는지 비교해야 합니다. 그렇다면 다음 단계로 넘어가겠습니다.
나는 이것을 시도하고있다
((((?:[^|]*\|){17}(.*?)\|)+\|[^|]*$)|[^|]+(?=(\,\H\,))|(^([0-9]){4})|(([RAV]){3}))
하지만 첫 번째, 두 번째 또는 다른 필드가 "RAV"인 경우에도 이는 일치합니다. 필드 15에서 정확히 일치하는 항목이 필요합니다.
답변1
반드시 정규식을 사용할 필요는 없습니다.
그리고 awk
:
awk -F '|' '$15 == "RAV" { print }' myfile
myfile
이렇게 하면 15번째 |
구분 필드가 정확히 string 인 파일의 모든 줄이 인쇄됩니다 RAV
. 이는 정규식 일치보다는 문자열 비교를 사용합니다.
RAV
15번째 필드의 어느 위치에서나 부분 문자열로 일치시키 려면 다음을 사용하십시오.
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
명령 포함) 에서 는 print
15번째 필드가 일치한다고 판단한 후 데이터에 대해 수행해야 하는 모든 작업을 나타냅니다 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