awk 및 sed를 사용하여 문자의 하위 문자열 바꾸기

awk 및 sed를 사용하여 문자의 하위 문자열 바꾸기

매우 긴 문자열이 포함된 파일이 있는데 해당 하위 문자열을 N으로 바꾸고 싶습니다. 예:

시험

ABCDABCDABCD

awk 명령과 sed를 사용하여 하위 문자열을 모든 문자 N(인덱스 5에서 8까지의 모든 문자)으로 바꾸고 싶으므로 문자 N의 총 길이는 4입니다.

산출

ABCDNNNNABCD

나는 다음과 같은 것을 시도했습니다 :

awk '{ v=substr($0,5,4); sed -i "s/$v/N/g";print substr($0,1,4)""v""substr($0,9,12)}' test

그러나 이 명령은 다음과 같은 출력을 제공하는 것으로 보입니다.

ABCDABCDABC

그리고 교체가 이루어지지 않았습니다

교체를 시작할 위치의 인덱스 번호(예: 여기서는 5)와 교체 길이 번호(여기서는 4)를 코드에 포함하고 싶습니다. 따라서 시작하려는 경우 해당 숫자를 수정할 수 있습니다. 실제로 수천 개의 문자로 구성된 문자열이 있고 수백 개의 문자를 바꾸고 싶기 때문에 제 경우에는 패턴 대체가 작동하지 않기 때문에 다른 위치에서 다른 길이 대체를 수행하십시오.

답변1

GNU awk를 사용하면 다음을 수행할 수 있습니다.

gawk -v start=5 -v end=8 '{
    mid = substr($0, start, end-start+1)
    print substr($0, 1, start-1) gensub(/./, "N", "g", mid) substr($0, end+1)
}' file

아니면 펄을 사용하세요

perl -spe 'substr($_, $start-1, $end-$start+1) =~ s/./N/g' -- -start=5 -end=8 file

두 솔루션 모두 명령줄 옵션을 사용하여 시작 및 종료 값을 프로그램에 전달합니다. 이렇게 하면 쉘 스크립트에서 값을 쉽게 변경할 수 있습니다. 대체 역할 N을 동적으로 만들어야 하는 경우 이를 수행하는 방법은 매우 명확해야 합니다.

답변2

GNU awk(gawk)가 있는 경우 FIELDWIDTHS문자 위치에 따라 행이 필드로 분할되도록 설정할 수 있습니다. 이는 "와일드카드" 후행 필드 너비를 지원하는 gawk 버전 >= 4.2에서 특히 편리합니다. 그런 다음 두 번째 필드의 문자를 다음으로 바꿀 수 있습니다 gsub.

echo ABCDABCDABCD | ./gawk -v i=5 -v n=4 '
  BEGIN {FIELDWIDTHS = sprintf("%d %d *", i-1, n)} 
  {gsub(/./,"N",$2)} 1
' OFS=""
ABCDNNNNABCD

이전 버전의 gawk에서는 *후행 필드에 대해 적절하게 큰 최대 크기를 선택하여 이를 시뮬레이션할 수 있습니다.

echo ABCDABCDABCD | gawk -v i=5 -v n=4 '
  BEGIN {FIELDWIDTHS = sprintf("%d %d 65536", i-1, n)} 
  {gsub(/./,"N",$2)} 1
' OFS=""
ABCDNNNNABCD

바라보다

고정 너비 데이터 처리

선택적 추적 데이터 캡처

답변3

다음 명령을 사용해 볼 수 있습니다.

 echo "ABCDABCDABCD"| sed "s/ABCD/NNNN/2"

산출

ABCDNNNNABCD

답변4

POSIX 또는 GNU seds에 표시된 대로 다음 방법을 사용하여 이를 수행할 수 있습니다.

sed 편집기를 사용하십시오:

$ L=5 R=8
$ sed -e '
   s/./\n/'"$L"';s//\n/'"$R"';ta
   :a;s/\n\n/NN/;t
   s/\n./N\n/;ta
' ./test

ABCDNNNNABCD

펄 사용:

perl -lspe '
   my $c = $idxr - (pos()=$idxl-1);
   s/\G.{$c}/"N"x$c/e;
' -- -idxl=5 -idxr=8 ./test

ABCDNNNNABCD

관련 정보