2

このコマンドの使用方法:

perl -pi -e 's/[^[:ascii:]]/#/g' file

各行のオフセット A の文字のみをオフセット B に変更するには?

4

2 に答える 2

7

あなたの質問を正しく理解できなかったという留保の下で、オフセット A と B が 5 と 10 の場合、次のようになります。

  perl -pi -e 's/(?<=.{5})(?<!.{10})[^[:ascii:]]/#/g' file

説明:

   [^[:ascii:]]  <- the character which is looked for
   (?<=.{5})     <- if at least 5 chars were before (offset 5)
   (?<!.{10})    <- but no more than 10 characters before (offset 10)

コンストラクト:

   (?<= ...) and (?<! ...)

これらは、肯定的および否定的な後読みと呼ばれ、アサーションを伴うゼロです。(それらをググることができます。 perlre の Look-Around Assertions セクションを参照しください)


補遺 1タイトルで 言及さsubstr()れていましたが、最初に見落としていました。もちろん、これも機能します。

  perl -pi -e 'substr($_,5,10)=~s/[^[:ascii:]]/#/g' file 

の説明はsubstr EXPR,OFFSET,LENGTHperldoc にありますsubstr()この例は、 を左の値として 使用することをうまく示しています。


補遺 2 この投稿を更新するとき、Grrrrは回答として同じ解決策を追加しましたが、彼は 1 分で最初に来ました! (だから彼は戦利品に値する)

よろしく

rbo

于 2012-06-28T09:14:08.767 に答える
7

ゴム長靴の答えの代わりに、文字列全体ではなく部分文字列を操作することもできます。

perl -pi -e 'substr($_, 5, 5) =~ s/[^[:ascii:]]/#/g' file

説明する:

perl -e 'print "\xff" x 16' | \
perl -p -e 'substr($_, 5, 5) =~ s/[^[:ascii:]]/#/g' | \
hd

印刷します

ff ff ff ff ff 23 23 23  23 23 ff ff ff ff ff ff

このコードでは、最初のオフセットは 0 ベースであり、2 番目のオフセットの代わりに長さを使用する必要があるため、 substr($_, A-1, B-A).

于 2012-06-28T09:37:38.333 に答える