Заменить последнее вхождение символа в файл - PullRequest
0 голосов
/ 09 марта 2011

У меня есть этот скрипт AWK, который заменяет каждый символ перевода формы (0x0C, 12) на 5 символов новой строки:

f=${*:-"-"}
awk 'BEGIN {FF=sprintf("%c",12); LF=sprintf("\n\n\n\n\n")}
     {i1=0;for(i2=i1+1;i2<=length($0);i2++) if(substr($0,i2,1) == FF)
     {print substr($0,i1+1,i2-i1-1) LF;  i1=i2}
      print substr($0,i1+1,length($0)-i1)}' $f

Теперь я хочу заменить только последним вхождением этого символа в файле.Не могу придумать простого решения.Как мне определить последнюю строку?Есть идеи?

AWK предпочтительнее (проблемы с производительностью).

Ответы [ 3 ]

1 голос
/ 10 марта 2011
sed '/\f/!b;:a;$!N;/\n.*\f/{h;s/\n[^\n]*$//p;s/^.*\n//;};$!ba;s/^\(.*\)\f/\1\n\n\n\n\n/' inputfile

Объяснение:

  • /\f/!b - Если строка не содержит FF, разветвитесь до конца и напечатайте ее
  • :a - Метка "a "
    • $!N - если это не последняя строка, добавьте следующую строку
    • /\n.*\f/{ - если в новой добавленной строке есть FF, то
      • h - сохранить накопленные строки в удерживающем пространстве
      • s/\n[^\n]*$//p - удалить последнюю накопленную строку и распечатать остальные
      • g - восстановить накопленные строки из удерживающего пространства
      • s/^.*\n// - Удалить все, кроме последней накопленной строки
    • } - Завершить, если
    • $!ba - Если это не последняя строка,переход к метке "a"
  • s/^\(.*\)\f/\1\n\n\n\n\n/ - Заменить последний FF в файле на пять новых строк

Обратите внимание, что это работает, даже если последний FFне в последней строке.

Вот как это сделать в AWK:

awk '/\f/ {
         print accum;
         accum = $0;
         next
     }
     {
         accum = accum "\n" $0
     }
     END {
         match(accum, ".*\f");
         print substr(accum, 1, RLENGTH - 1) "\n\n\n\n\n" substr(accum, RLENGTH + 1)}'
     }' inputfile

Он сохраняет в памяти только то, что должен.

0 голосов
/ 09 марта 2011

Вот строка perl с одной строкой, которая считывает все содержимое в память и заменяет последний возврат каретки:

perl -0777 -pe 's{\r([^\r]*)\z}{\n\n\n\n\n\1}' "$f"

или

perl -0777 -pe '
  $pos = rindex($_, "\r"); 
  substr($_, $pos, 1) = "\n\n\n\n\n" if $pos != -1
' "$f"
0 голосов
/ 09 марта 2011

Я не знаю awk достаточно, чтобы сделать это, но это возможно с sed:

sed -e '$s/\x0C$/\x0C\x0C\x0C\x0C\x0C/' your_file

\x0C обозначает символ с шестнадцатеричным кодом ascii 0C, как вы, вероятно, догадались.

Если вы хотите изменить свой файл в файле, вместо вывода результата сценария в стандартный вывод, добавьте параметр -i.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...