sed / awk условно удаляет строки из начала и конца файла - PullRequest
0 голосов
/ 02 августа 2020

У меня есть несколько тысяч текстовых файлов, которые могут начинаться с

"

Start of text

, но не все из них имеют одинаковое количество разрывов строки, и не все из них имеют "

I хотел бы удалить " (если он существует) и любые разрывы строк, если они есть.

(и конец тоже, но я, вероятно, разберусь, если вы покажете мне, как удалить его с самого начала )

End of file...

"

perl тоже нормально

моя попытка будет примерно такой с оболочкой fi sh. awk, вероятно, более производительный, хотя

if head -1 | grep \"
    sed -i 1d $file
if head -1 | grep '^\r\n$'
    sed -i 1d $file
if head -1 | grep '^\r\n$'
    sed -i 1d $file
if head -1 | grep '^\r\n$'
    sed -i 1d $file

это может действительно сработать Я собираюсь попробовать

Ответы [ 4 ]

1 голос
/ 03 августа 2020

Вы также можете использовать ed, чтобы сделать это за один проход:

Что-то вроде

printf '%s\n' '1g/^"$/.,/^./-1d' '$g/^"$/?^.?+1,$d' w | ed -s "$file"

Переведено: Если первая строка - не что иное, как цитата, d удалите его и все следующие пустые строки. Если последняя строка - не что иное, как цитата, удалите все предыдущие пустые строки и ее. Наконец, w записать файл обратно на диск.

1 голос
/ 02 августа 2020

Самый простой способ сделать это - двухпроходный подход, когда на первом проходе вы определяете номера начальной и конечной строк для «хороших» строк, а на втором вы печатаете строки между этими числами:

awk '
    NR==FNR { if (NF && !/^"$/) { if (!beg) beg=NR; end=NR } next }
    (beg <= FNR) && (FNR <= end)
' file file

Например, при этом вводе:

$ cat file
"

Start of text

but not all of them have the same number of line breaks and not all of them have "

I would like to remove " (if it exists) and any line breaks, if any.

(and the ending too but I'll probably figure it out if you show me how to remove it from the start)

End of file...

"

Мы можем сделать следующее, используя любой awk в любой оболочке в каждом UNIX поле:

$ awk 'NR==FNR{if (NF && !/^"$/) {if (!beg) beg=NR; end=NR} next} (beg <= FNR) && (FNR <= end)' file file
Start of text

but not all of them have the same number of line breaks and not all of them have "

I would like to remove " (if it exists) and any line breaks, if any.

(and the ending too but I'll probably figure it out if you show me how to remove it from the start)

End of file...
0 голосов
/ 03 августа 2020

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

sed '1{/^"$/d};/\S/!d;:a;${/^"$/Md};/\S/{n;ba};$d;N;ba' file

Удалить первую строку, если она содержит единственную ".

Удалить все пустые строки с начала файла .

Форма al oop для оставшейся части файла.

Удалить последнюю строку (строки), если она / они содержат одну ".

Если текущая строка (строки) не пуста, распечатайте ее / их, выберите следующую и повторите.

Если текущая строка (строки) является последней и пустой, удалите ее / их.

Текущая строка (строки) пуста, поэтому добавьте следующую строку и повторите.

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

Альтернатива, требует много памяти:

sed -Ez 's/^"?\n+//;s/\n+("\n)?$/\n/' file
0 голосов
/ 02 августа 2020

В дополнение к двухпроходной обработке, вот однопроходная:

awk '!/^"*$/{print b $0;f=1;b=""} f&&/^"*$/{b=b $0 ORS}' file

Программа состоит из двух небольших частей:

  1. Когда есть содержимое (строки, содержащие более "), распечатать возможно буферизованные строки и текущую строку ввода, установить флаг начала содержимого и очистить буфер.

  2. Если содержимое началось (f), но текущая строка не содержит содержимого, возможно, мы достигли конца, поэтому мы буферизуем эти пустые строки. Позже (1) напечатает их, иначе они будут отброшены в EOF.

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