다음 내용이 포함된 "SAMPLE.txt"라는 파일이 있습니다.
P1
10,9:6/123456
P2
blah blah
P1
10,9:5/98765
P2
blah
blah
P1
blah blah
P2
출력 파일 "RESULT.txt"를 원합니다.
Value1:123456
Value2:98765
Value3:NULL
먼저 P1과 P2 부분 사이의 콘텐츠를 가져온 다음 10,9*/ 값을 찾아 다른 값으로 저장해야 합니다. 특정 P1-P2 블록에 이 값이 없으면 "NULL"로 저장하고 싶습니다.
위의 코드를 shell/awk에 어떻게 작성하나요?
저는 스크립팅을 처음 접했습니다.
답변1
이것은 작동하며 완전히 이식 가능합니다.
sed '\|^P1.*|!d;s||Value:|
:n
N;\|\nP2|!bn
s|:.*\n10,9[^/]*/|:|
s|\n.*||;s|:$|:NULL|'
프로세스는 다음과 같습니다.
먼저
^
다룹니다.P1
현재 행이
!
일치하지 않으면d
삭제됩니다.그렇다면 다음
P1
으로 교체하십시오.Value:
:n
그런 다음 ext 태그를 설정 하고N
ext 라인을 가져옵니다.찾을
\nP2
수 없으면 ext 태그 로 돌아가서 찾을 때까지 다시 시도하세요.!
b
:n
:.*\n10,9
그런 다음 첫 번째 발생/
까지 모든 문자 발생을 제거합니다 .\n
사용 가능한 첫 번째 ewline과 모든 후속 문자를 제거합니다 .:
마지막 문자가 뒤에 오는 콜론 이면Value
문자열이 삽입됩니다NULL
.
6단계와 7단계가 작동합니다. 6단계에서는 \n
원하는 숫자 문자열 앞에 있는 ewline을 제거하지만, 없으면 다음 \n
ewline은 바로 다음의 문자열이 됩니다 Value:
.모든 것7단계로 이동합니다.
이것이 실제로 작동하는 것입니다:
sed '\|^P1.*|!d;s||Value:|
:n
N;\|\nP2|!bn
s|:.*\n10,9[^/]*/|:|
s|\n.*||;s|:$|:NULL|' <<\DATA
P1
10,9:6/123456
P2
blah blah
P1
10,9:5/98765
P2
blah
blah
P1
blah blah
P2
DATA
산출:
Value:123456
Value:98765
Value:NULL
답변2
사용 perl
(전체 파일을 메모리에 저장하더라도):
perl -0777 -ne 'while (/P1\n(.*?)\nP2/gs) {
printf "Value%d:%s\n", ++$n, $1 =~ /^10,9.*\// ? $'\'': "NULL"}'
답변3
일방 perl
통행:
$ perl -F'/' -alne '
if (/P1/../P2/ and $_ !~ /^P/) {
print "Value@{[++$i]}:",$F[1]?$F[1]:"NULL";
}
' file
Value1:123456
Value2:98765
Value3:Null
해결책 awk
:
$ awk -F'/' '/P2/{f=0};/P1/{f=1;next};f{print "Value"++i":"($2?$2:"Null")}' file
Value1:123456
Value2:98765
Value3:Null
답변4
다들 감사 해요. 마침내 내 문제를 해결한 코드 조각은 다음과 같습니다.
nawk -v fname="${filename}" -F '/|:' '
function isnum(x){return(x==x+0)}
/P1/,/P3/{
# Found start increment i reset variables go to next line
if(/P1/){
++i
fid =""
count++
next
}
# Found end validate variable and print go to next line
if(/P3/){
printf "%s|",count
printf "%s|",isnum(fid)?fid:"NULL"
next
}
if(!fid && /36,59:*/)
{
fid = $NF
}
' ${filename} >>output.txt
하지만 이제 또 다른 문제가 생겼고 이에 대해 별도의 스레드를 만들었습니다.
여러분이 도움을 줄 수 있다면 여기 링크를 참조하세요.