非常に長い文字列を含むファイルがあり、その部分文字列を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で特に便利です。その後、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