Linuxコマンドでファイル内の最後の5つの文字列を置き換える方法は? [閉鎖]

Linuxコマンドでファイル内の最後の5つの文字列を置き換える方法は? [閉鎖]

Linuxコマンドを使用してファイル内の最後の5つの文字列を置き換えたいと思います。

アドバイスしてください。

例:

入力が期待される出力にababa ababa ababa ababa ababa ababa
置き換えられました。abaabX
ababa abXba abXba abXba abXba abXba

入力は実行の出力にababa ababa ababa ababa ababa ababa ababa
置き換えられます。aba12
ababa ababa 12ba 12ba 12ba 12ba 12ba

注:文字列は複数行にまたがるか、ファイルのどこにでも配置できます。しかし、最近5試合だけを交換したいと思います。

ファイルに一致するものが100個ある場合、最後の5つの一致が置き換えられます。

答え1

そしてperl

perl -0777 -pse '
  $count = () = /\Q$string\E/g;
  s{\Q$string\E}{$count-- > $n ? $& : $replacement}ge
  ' -- -string='whatever
even multiple
lines' -replacement='whatever as well' -n=5 -- file

標準出力に結果を送信するのではなく、場所で編集できる-iオプションが追加されました。file

  • -pファイルのすべてのレコードに対して渡された式sedのコードを評価するパターンです。e-e
  • -0777レコード区切り文字を不可能なバイト値に設定します。これは、ファイルの全内容であるレコードが1つだけあることを意味します。
  • -s-varname=value変数の値をパラメータとして渡すことができます。
  • /regexp/g$_ =~ m{regexp}gは現在のレコード(in)に適用され、正規表現がスカラーコンテキストregexpで一致し、一致リストがリストコンテキストで一致する場合はtrue / falseを返すグローバルアッチャの略語です。ここで正規表現は次のとおりです。m$_\Q$string\E\Q\E引用する$stringso は正規表現演算子を含んでいてもリテラル文字列として扱われます。
  • を使用すると、空の() = /regexp/g変数リストに割り当ててリストコンテキストを強制するため、デフォルトでそのエントリを削除しますが、結果はスカラー割り当てに使用されるため、要素数と一致数が提供されます。正規表現なので、$stringレコードの発生回数(の全内容file)です。
  • s{regexp}{replacement}ge:Perlコード式として解釈されるグローバルに一致する.forを置き換えsます。gregexpreplacementereplacement
  • condition ? iftrue : iffalseほとんどの言語で見られる一般的なC三項演算子です。
  • $count--$count前の増分を返します。一致するものが含まれているもの< $nに置き換えると、何も実行せず、に置き換えない限り、何もしません。$&$replacement

答え2

これはawkとsedを使用する1つの方法です。次のようにして、ファイル内の文字列の発生回数を計算します。

grep -o mystring file1.txt | wc -l

この数が20だとしましょう。次に、最初の20-5 = 15項目をランダムな文字列に置き換えます(例:PWWP)。

awk '{for(i=1;i<=NF;i++){if(c<15&&$i=="mystring"){c++;sub("mystring","PWWP",$i)}}}1' file1.txt > file2.txt

sedを使用して、file2.txtから残りの一致(5項目)をすべて削除します。

sed -i 's/mystring//g' file2.txt

そして、2番目のsed操作で元のファイルを復元します。

sed -i 's/PWWP/mystring/g' file2.txt
mv file2.txt file1.txt

関連情報