Sed: как заменить nextline \n символ в текстовых файлах?

Ваше единственное решение может состоять в том, чтобы записать Вашу собственную файловую систему пространства пользователя или способствовать существующей. Посмотрите на частичный список в Файловой системе в Пространстве пользователя

Если у Вас нет навыков для содействия, предложите рекламу проекта или $$$ или обоих, для добавления его для Вас.

Мне жаль, что у меня не было времени, чтобы сделать это, я всегда хотел что-то точно как это.

3
21.11.2018, 00:26
3 ответа

Sed обрабатывает свой вход линию за линией, таким образом, символ новой строки никогда не будет спонтанно появляться во входе. То, что Вы могли сделать, вставляется в окончание строк </time в ожидании; затем, если следующая строка начинается <geo>, сделайте замену в предыдущей строке. (Это возможно в sed, использование “содержит пространство”, но я рекомендую обратиться к awk или жемчугу, когда Вам нужно пространство хранения.)

Однако, учитывая Ваш демонстрационный вход, можно просто измениться </time> в </tags> когда строка начинается <tags>.

sed -e '/^<tags>/ s!</time>$!</tags>!'
3
27.01.2020, 21:17

Хотя, возможно, решение Вашей проблемы может быть легко достигнуто другими способами, ответ на Ваш вопрос прост. sed, по умолчанию, работает линия одновременно на 2 буферах - один постоянный поперечный цикл, называемый старым пространством h, и один обновлённый хотя бы один раз за цикл, называемый пространством шаблона, - и в последнем случае выполняются все правки.

Взгляд вперед может быть получен одним из двух способов - можно сохранить старые линии и отстать от цикла линий, чтобы лучше использовать команды для подкачки и сравнения буферов. Для этого используются такие примитивы команд, как [hH] old, [gG]et, exchange - которые сохраняют в буфер удержания, копируют из него и выкачивают из него соответственно, - а нижние регистровые формы перезаписывают и верхний регистр форм добавляют к своему целевому буферу.

Или вы можете работать с будущими строками в постоянном алгоритме редактирования, в котором вы последовательно удаляете столько входных строк, сколько вы читаете за цикл. Последнее было бы здесь предпочтительнее - особенно потому, что sed делает это очень просто и эффективно - особенно с помощью команд N;P;D.

Вот демо-версия, использующая данные Вашего примера:

sed '$!N;s/ime\(>\n<geo\)/ags\1/;P;D
'  <<\IN
<time>20260664</time>
<tags>substancesummit ss</time>
<geo>asdsadsa</geo>
<time>20260664</time>
<tags>substancesummit ss</time>
<geo>asdsadsa</geo>
IN

Next, Print, и Delete, как и их нижние регистры n;p;d получают следующую строку ввода, распечатывают и удаляют в/из шаблонного пространства, соответственно. В отличие от своих нижних регистровых аналогов (если немного меньше, чем в случае N), эти три строки работают на новых границах, а не в пространстве образца в целом.

  • N добавит следующую входную строку в пространство образца после символа \newline.
  • P распечатает только до появления первого \n-символа овечьей линии в пространстве шаблона.
  • D будет удалять только до первого возникающего \nовечьего символа в пространстве шаблона до выхода из сценария для текущего цикла и постановки в очередь следующего с тем, что осталось в пространстве шаблона, или, если ничего не останется после его удаления, то следующая строка будет ожидаться на входе, как обычно.

Эти трое могут работать вместе, расширяя окно редактирования sed в файле очень просто и эффективно - sed скользит по файлу, распечатываемому за цикл, только самая старая из серии строк, которую он последовательно удаляет и пополняет в соответствии с инструкциями скрипта - что оставляет sedder ответственным за цикл строк.

И взгляд на следующую строку легко расширяется. Если бы вам понадобилось 4-строчное окно с шаблоном во всем скрипте, вы могли бы сделать:

sed -e '1{N;N' -e '};N;...;P;D'

... или, возможно, более полезным....

sed -e ':next
    $!{/\(.*\n\)\{3\}/!{
        N;b next' -e '}
    };...cmds...;P;D'

... в котором sed только отрисовывает входную строку - и продолжает это делать до тех пор, пока ей не будет достаточно для выполнения любых других команд - если в пространстве шаблона меньше трёх \newline символов, а текущая строка не последняя. Это происходит независимо от того, какие правки могут быть сделаны последующими командами.

2
27.01.2020, 21:17

Чтобы литературно ответить на вопрос:

Я решаю эту проблему (текст для редактирования охватывает несколько строк) небольшим обманом:

cat input.txt | tr '\n' '@' | sed -e 's/txt@iam@interestedin/iaminterested@intxt/g' | tr '@' '\n' > output.txt

Единственное, в чем вы должны быть уверены, так это в том, что символ, которым вы заменяете новую строку, еще не существует во входных данных.

0
27.01.2020, 21:17

Теги

Похожие вопросы