Как избежать последнего перехода на новую строку в sed? - PullRequest
0 голосов
/ 26 февраля 2019

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

Итак, остановившись на «STOP», следующийfile:

keep\n
STOP\n
whatever

Должен вывести:

keep

Без завершающего перевода строки.

Я пробовал это, и логика, кажется, работает, но кажется, что sedдобавляет новую строку каждый раз, когда он печатает свой буфер.Как я могу избежать этого?Когда sed не манипулирует буфером, у меня такой проблемы нет (т.е. если я удаляю STOP, sed выводит «что угодно» в конец файла без перевода строки).

printf 'keep
STOP
Whatever' | sed 'N
/\nSTOP/ {
  s/\n.*$//
  P
  Q
}
P
D'

Iпытаюсь написать фильтр очистки git, и я не могу добавлять новую строку каждый раз, когда я фиксирую.

Ответы [ 3 ]

0 голосов
/ 26 февраля 2019

Это может сработать для вас (GNU sed):

sed -z 's/\nSTOP.*//' file

Опция -z выгружает весь файл в память и команду замены, удаляет оставшуюся часть файла с первой новой строки, за которой следуетSTOP.

0 голосов
/ 26 февраля 2019
$ awk '/^STOP/{exit} {printf "%s%s", ors, $0; ors=RS}' file
keep$

Приведенное выше печатает каждую строку без завершающего символа новой строки, но предшествует новой строкой (\n или \r\n - в зависимости от того, что диктует ваша среда, чтобы она работала правильно в UNIX или Windows иличто угодно) для каждой второй и последующих строк.Когда он находит строку STOP, он просто выходит перед печатью чего-либо.

Обратите внимание, что вышеупомянутое ничего не сохраняет в памяти, кроме текущей строки, поэтому оно будет работать независимо от того, насколько велик ваш входной файл и не имеет значениягде в нем появляется STOP - он будет работать даже в том случае, если STOP - первая строка файла, в отличие от других ответов, которые у вас есть.

Он также будет работать с использованием любого awk в любой оболочке на каждом компьютере UNIX..

0 голосов
/ 26 февраля 2019

Используя awk, вы можете:

$ awk '$0=="STOP"{exit} {b=b (b==""?"":ORS) $0} END{printf "%s",b}' file

Вывод:

keep$

Объяснено:

$ awk '                        
    $0=="STOP" { exit }        # exit at STOP, ie. go to END
    { b=b (b==""?"":ORS) $0 }  # gather an output buffer, control \n
    END { printf "%s",b }      # in the END output output buffer
' file    

... больше (сосредоточив внимание на условный оператор ):

    b=b             # appending to b, so b is b and ...
    (b==""?"":ORS)  # if b was empty, add nothing to it, if not add ORS ie. \n ...
    $0              # and the current record
...