Text-Processing

僅對子字元串進行更改操作

  • January 15, 2022

START在一個文件中,在一個由模式和標記的部分之前和之後有任何亂碼文本END(特定字元串每個只出現一次,並且以正確的順序出現在同一行上)。我想只對和之間的部分進行一些字元串START操作END

範例輸入:

aomodi3hriq32| ¶³r 0q93aoiSTART_this_is_to_be_modified_ENDaqsdofuha23uru| ²23i ii3uhfia
oawpo3<9"§ A hSTART_this_also_needs_modification_ENDqa 032/a237(°1Q"§ >A_this_
START changeme ENDnot_this_modias

在 - 操作方面,應該修改和sed之間的子字元串(和僅子字元串),就像我使用.START``END``sed 's/_this_// ; s/modi/MODI/ ; y/as/45/'

範例輸出:

aomodi3hriq32| ¶³r 0q93aoiSTARTi5_to_be_MODIfied_ENDaqsdofuha23uru| ²23i ii3uhfia
oawpo3<9"§ A hSTART4l5o_need5_MODIfic4tion_ENDqa 032/a237(°1Q"§ >A_this_
START ch4ngeme ENDnot_this_modias

awkwithFS="START|END"失敗,因為OFS不能在不同位置設置多個值。

我嘗試使用sed嵌套命令替換和不同的分隔符 ( ~) 但失敗了,並且還擔心之前START/之後可能有字元END會與命令混淆(例如 a /)。這個想法是只選擇“內部”子字元串並執行操作,然後將其用作替換的一部分:

sed "s/^\(.*\)START.*END\(.*\)$/\1$(sed 's~^.*START~~
                                        s~END.*~~
                                        s~_this_~~
                                        s~modi~MODI~
                                        y~as~45~' infile)\2/" infile

我不熟悉例如perl….但無論如何。

有沒有辦法讓一組 -sed操作僅適用於一行的 REGEX 匹配的子字元串?

perl -CSD -ne '
   if (my ($before, $between, $after) = /^(.*START)(.*)(END.*)/) {
       s/_this_//, s/modi/MODI/, tr/as/45/ for $between;
       print "$before$between$after\n";
   } else { print; }' -- file
  • -CSD解碼來自 UTF-8 的輸入並將輸出編碼為 UTF-8
  • 除了填充三個變數$before,$between$after,我們可以使用/pand ${^PREMATCH}${^POSTMATCH}但我沒有找到更好的解決方案:
if (my ($s) = /START(.*)END/p) {
   s/_this_//, s/modi/MODI/, tr/as/45/ for $s;
   print "${^PREMATCH}START${s}END${^POSTMATCH}";
} else { print; }

如果 START…END 部分可以在一行上重複,則需要遍歷每一行。

for my $part (split /(START.*?END)/) {
   if ($part =~ /^START.*END$/) {
       s/_this_//, s/modi/MODI/, tr/as/45/ for $part;
   }
   print "$part";
}

引用自:https://unix.stackexchange.com/questions/686124