필드 문자의 하위 문자열을 제거하지 마세요.

필드 문자의 하위 문자열을 제거하지 마세요.

awk에서 하위 문자열(또는 잘라내기, sed 등)을 원하는 문자열이 있습니다.

하지만 필드 구분 기호를 유지하고 싶습니다.

파일에는 필드 구분 기호 뒤에 임의의 문자 수가 포함된 완전히 임의의 양의 쓰레기가 있습니다.

예를 들어

dog.pgp.123sdadog.pgpsjaksdasdasdawdog.pgp -
asasdawad2

세 가지 출력이 모두 다음과 같기를 바랍니다.

개.pgp

분명히 여기의 공개 필드는 ".pgp"이지만 표준 awk는 항상 필드 구분 기호를 제거합니다.

'{sub(/.pgp.*/,""); print}'

또는

awk -F".PGP." '{print $1}'

분리막을 유지할 수 있는 방법이 있나요?

답변1

for string in Dogs.pgp.123sda Dogs.pgpsjaksdasdasdaw Dogs.pgp-asasdawad2
do
    printf '%s --> %s\n' "$string" "${string%${string#*.???}}"
done

산출:

Dogs.pgp.123sda --> Dogs.pgp
Dogs.pgpsjaksdasdasdaw --> Dogs.pgp
Dogs.pgp-asasdawad2 --> Dogs.pgp

이 루프는 세 개의 문자열을 반복합니다. 루프 본문에는 원래 문자열이 변환된 문자열과 함께 인쇄됩니다.

첫 번째 점 앞의 문자열 부분과 점 뒤의 세 문자를 제외한 모든 부분을 제거하여 문자열을 변환합니다.

이 작업은 먼저 원래 문자열에서 제거할 항목을 파악하여 수행됩니다. 이것은 ${string#*.???}첫 번째 점과 세 개의 문자를 더 제거한 후의 나머지 문자열입니다. 그런 다음 문자열 끝에서 해당 값을 제거합니다 ${string%${string#*.???}}.

루프가 반복되는 경우파일 이름예를 들어 와 일치 *.pgp*하면 파일 이름에 개행 문자가 포함된 경우도 처리할 수 있습니다. 위의 변환을 혼란스럽게 하는 유일한 것은 .pgp하위 문자열 앞에 점이 있는 경우이지만 .pgp대신 명시적으로 일치시켜 이를 수행할 수 있습니다 .???.

for fname in *.pgp*
do
    printf '%s --> %s\n' "$fname" "${fname%${fname#*.pgp}}"
done

답변2

어때요?

awk -F '.pgp' '{print $1 FS}'

대신 awk를 사용하고 싶습니다 perl -pe 's/\.pgp\K.*//'.

답변3

일치 및 하위 문자열을 사용하여 문제를 해결했다고 생각합니다.

'match($0, /REGEX/) {sub(/REGEX/, substr($0, RSTART, RLENGTH) ); print}'

답변4

awk substr 방법을 사용해 보았습니다.

awk '{print substr($1,1,8)}' filename

출력은 다음과 같습니다

Dogs.pgp
Dogs.pgp
Dogs.pgp

관련 정보