식별자가 포함된 레코드가 포함된 파일이 있습니다. 각 식별자에 대해 여러 레코드가 있을 수 있습니다. 동일한 식별자를 가진 모든 레코드를 검색하고 해당 레코드에서 특정 패턴(특정 위치의 Y)을 찾고 싶습니다. 패턴이 있으면 이 메트릭의 첫 번째 레코드를 해당 패턴으로 업데이트하고 싶습니다. 스크립트를 통해 이를 가장 잘 달성하려면 어떻게 해야 합니까? (유닉스 또는 윈도우즈). 파일은 식별자별로 정렬됩니다.
다음은 제가 달성하려는 작업의 예입니다.
identifier1aaaNbbb
identifier1cccNddd
identifier1eeeYfff
식별자 1에 대한 레코드 중 하나의 위치 14에 "Y"가 있는 경우 해당 "Y"는 식별자 1에 대한 레코드의 첫 번째 항목에 기록됩니다.
identifier1aaaYbbb
identifier1cccNddd
identifier1eeeYfff
awk
어떤 도구( , grep
, sed
)가 이 작업에 가장 적합한지 잘 모르겠습니다 . 문제를 해결하는 방법을 아시나요?
답변1
입력 파일을 두 번 사용 awk
하고 읽어 처리합니다.
Y
이는 귀하의 식별자 길이가 11자이고 줄의 15번째 문자를 찾고 있다고 가정합니다 (귀하의 예에서와 같이). 식별자 길이가 항상 11자가 아닌 경우 스크립트의 첫 번째 줄을 수정해야 합니다.
첫 번째 통과: 각 식별자의 첫 번째 레코드를 배열에 저장하고 Y
레코드가 발견되면 이 배열 요소를 수정합니다.
두 번째 단계: 각 식별자의 첫 번째 레코드 줄을 저장된 및 수정된 배열 값으로 바꾸고 해당 줄을 인쇄합니다.
awk '{
ident=substr($0,0,11) # get identifier
if (NR==FNR){ # first pass
if (!(ident in a)){ # if identifier is not present in array
a[ident]=$0 # save current line in array
}
if (substr($0,15,1) == "Y"){ # if `Y` is found in current line
# replace character with `Y` in array value
a[ident]=substr(a[ident],0,14)"Y"substr(a[ident],16)
}
}
else { # second pass
if (ident in a){ # if identifier is present in array
$0=a[ident] # replace current line
delete a[ident] # delete array element
}
print # print current line
}
}' file file
답변2
아니요우아한. 참고용으로만 사용하세요.
먼저 모든 identifier1
레코드를 식별합니다
. command1: grep '^identifier1' my_file_name
그러면 인쇄됩니다.오직선택한 라벨이 있는 행입니다. 나중에 다른 식별자를 가진 레코드를 찾을 수 있습니다.
이러한 기록이 있으면 검색할 수 있습니다.오직열 14, cut 명령 사용:
command2: _command1_ | cut -c14
명확성을 위해 명령에 약칭 표기법을 사용했습니다. 그들이 당신에게 의미가 있기를 바랍니다. command2 14번째 문자( "char"의 경우)
만 인쇄하려면 cut 명령을 사용하십시오 . 그런 다음 이 출력에서 "Y"를 찾을 수 있습니다. command3: -q는 "조용함"을 의미하며 아무것도 출력하지 않습니다. 참고: 어떤 사람들은 rc가 필요하지 않다고 말합니다. $?만 보면 됩니다. 당신의 전화. 이 시점에서 $rc(또는 $?)가 0이면 grep은 적어도 하나의 대문자 Y를 찾습니다. 그렇지 않으면 1(오류를 나타내는 다른 숫자일 수도 있음)입니다. 다음과 같이 코딩해 보겠습니다. 참고: 사이에 명령을 입력하고 $?를 사용해야 하는 경우에는 $?를 사용하면 됩니다. N의 모든 표시기를 Y로 변경하려면 다음 sed 명령을 실행할 수 있습니다. -c
_command2_ | grep -q Y
rc=$?
if [ $rc -ne 0 ] then echo "No Ys found" exit fi
grep -q Y
if
rc=$?
sed -i "/^식별자1/s/\(………….\).\(.*\)/\1Y\2/" my_file_name
-i
파일의 내부 편집을 나타냅니다 . 다음으로 시작하는 일치하는 줄만
말합니다 ./^identifier1/
표시기 1s
검색 및 교체를 의미합니다 . 다음 슬래시 이후에 검색/다음 슬래시로 대체합니다.
검색: 14번째 문자를 원합니다. 이를 수행하는 우아한 방법이 있습니다sed. 설명은 다른 사람들에게 맡기겠습니다. 간단한 대답은 다음과 같습니다.
-dot-는 모든 문자를 의미합니다. 따라서 13개의 점은 처음 13개의 문자가 일치한다는 의미입니다. 우리는 그것들을 그대로 유지하고 싶기 때문에 버킷에 보관합니다. is it (and) - 괄호를 피하십시오. 그래서:
/\( 13 dots \) . \( dot * \)
줄의 처음 13자를 가져와서 버킷 #1에 저장한다고 가정해 보겠습니다. 점은 1개의 문자와 일치함을 의미합니다. 점으로 표시된 별표는 "0개 이상의 문자 일치", 즉 다른 모든 항목을 버킷 #2에 저장한다는 의미입니다.
이제 바꾸기:
/\1Y\2/
행을 버킷 #1, Y, 버킷 #2의 내용으로 바꾸는 것을 의미합니다.
이를 정리하고 더 효율적으로 만드는 방법이 있습니다. 내 앞에는 Linux 상자가 없고 어떻게 해야 하는지 기억이 나지 않습니다.
다른 사람이 언제팹사람들이 게시한 내용이므로 지금쯤 이해하실 수 있을 것입니다.