매우 긴 문자열이 포함된 파일이 있는데 해당 하위 문자열을 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