Как удалить несколько пустых строк из файла?

Если Вы не выполните пред2.6 ядра, Вы не будете использовать int x80 метод для вызова большинства системных вызовов. Они были заменены в пользу systenter/sysexit метод начиная с ядра 2.6 (запустился в 2,5 рядах) для вещей тот вопрос.

Обратите внимание, что, если у Вас есть старые двоичные файлы, которые были созданы против более старых ядер, они могли все еще использовать int x80 метод - единственная вещь, которую можно сделать об этом, восстанавливает их (или получает обновленные двоичные файлы).
Выполненный ldd your_exe на программе Вы волнуетесь по поводу. Если это перечисляет linux-gate.so.1 или linux-vdso.so.1, это использует новый syscalls. В противном случае это (скорее всего), использует старый метод.
Для статических двоичных файлов более трудно сказать. Один путь был бы к objdump your_exe | less и ищите обертки системного вызова (__gettimeofday хороший кандидат). Вы будете видеть от дизассемблирования, если оно будет использовать прерывание или нет.

Хорошее краткое изложение того, как старые вызовы INT 80 работали и как новый интерфейс syscall оказался и является установкой, может быть найдено здесь: Системные вызовы (Andries Brouwer).
Другое хорошее чтение: Кто такой linux-gate.so.1?.

Обе этих статьи связаны в этой другой: Основанный Механизм Системного вызова Sysenter в Linux 2.6 и точки к Пониманию Ядра Linux заказывают Daniel P. Bovet, Marco Cesati, который хорош для более общей информации.

Так короче говоря: не волнуйтесь об этом. Если у Вас есть достаточно недавняя система (ЦП, ядро и распределение), Вы используете "быстрые" системные вызовы.

14
08.07.2019, 13:13
7 ответов

Случай 1:

awk '!NF {if (++n <= 2) print; next}; {n=0;print}'

Случай 2:

awk '!NF {s = s $0 "\n"; n++; next}
     {if (n>1) printf "%s", s; n=0; s=""; print}
     END {if (n>1) printf "%s", s}'
14
27.01.2020, 19:50
  • 1
    +1 для awk вместо sed –  Rob 17.04.2013, 20:22
  • 2
    Так как этот вариант использования часто повторяется, я предложил бы создать сценарий. –  ChuckCottrill 11.10.2013, 02:43

Можно использовать uniq для сворачивания несколько инстанцируют пустых строк в одну пустую строку, но она также свернет строки, которые содержат текст, если они - то же и друг ниже друга.

15
27.01.2020, 19:50

Можно обратиться к Случаю № 1 как это с GNU sed:

sed -r ':a; /^\s*$/ {N;ba}; s/( *\n *){2,}/\n\n/'

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

Для присоединения к напечатанным через один интервал строкам, как, в случае, если № 2, можно сделать это как это:

sed -r '/^ *\S/!b; N; /\n *$/!b; N; /\S *$/!b; s/\n *\n/\n/'

Или в прокомментированной форме:

sed -r '
  /^ *\S/!b        # non-empty line
  N                # 
  /\n *$/!b        # followed by empty line
  N                # 
  /\S *$/!b        # non-empty line
  s/\n *\n/\n/     # remove the empty line
'
3
27.01.2020, 19:50

Случай 1:

perl -i -ane '$n=(@F==0) ? $n+1 : 0; print if $n<=2'

Случай 2:

perl -i -ane '$n=(@F==0) ? $n+1 : 0; print $n==2 ? "\n$_" : $n==1 ? "" : $_ '
6
27.01.2020, 19:50
  • 1
    +1 perl ftw! Awk является (вероятно), каноническим для этого, но (DRY) заставляет меня писать сценарии для примеров использования, которые повторяются как это. –  ChuckCottrill 11.10.2013, 02:42

lxdm находится в Debian нестабильно, но не в Wheezy. Но, возможно, вы сможете сделать это.

apt-cache policy lxdm
lxdm:
  Installed: (none)
  Candidate: 0.5.0-3
  Version table:
     0.5.0-3 0
         50 http://httpredir.debian.org/debian/ unstable/main amd64 Packages

Сборка, зависящая от lxdm , даны как:

apt-cache showsrc lxdm
...
Build-Depends: debhelper (>= 9), intltool, iso-codes, libck-connector-dev, libgtk2.0-dev, libpam0g-dev, libx11-dev, libxmu-dev, pkg-config, dh-systemd, po-debconf

Все это в Debian wheezy, за исключением dh-systemd , который находится в wheezy-backports. Попробуйте ввести доступные версии:

apt-cache policy debhelper intltool iso-codes libck-connector-dev libgtk2.0-dev libpam0g-dev libx11-dev libxmu-dev pkg-config dh-systemd po-debconf
-121--229796-

Неверный вызов сценария. Это должно быть:

#! /bin/bash
do-something
do-something-else
./myotherscript.sh;
-121--96831-

Следующее предложение Anthon использовать «uniq»...

Удаление начальных, конечных и дублирующих пустых строк.

# Get large random string.
rand_str=; while [[ ${#rand_str} -lt 40 ]]; do rand_str=$rand_str$RANDOM; done

# Add extra lines at beginning and end of stdin.
(echo $rand_str; cat; echo $rand_str) |

# Convert empty lines to random strings.
sed "s/^$/$rand_str/" |

# Remove duplicate lines.
uniq |

# Remove first and last line.
sed '1d;$d' |

# Convert random strings to empty lines.
sed "s/$rand_str//"

В одной длинной строке:

(rand_str=; while [[ ${#rand_str} -lt 40 ]]; do rand_str=$rand_str$RANDOM; done; (echo $rand_str; cat; echo $rand_str) | sed "s/^$/$rand_str/" | uniq | sed '1d;$d' | sed "s/$rand_str//")

Или просто используйте «cat -s».

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

# Add extra blank lines at beginning and end.
# These will be removed in final step.
{ echo; cat; echo; } |

# Replace multiple blank lines with a single blank line.
cat -s |

# Remove first and last line.
sed '1d;$d'

В одной строке.

{ { echo; cat; echo; } | cat -s | sed '1d;$d'; }
0
27.01.2020, 19:50

Это решение также заботится о последних пустых строках в файле:

sed -r -n '
  /^ *$/!{p;b}  # non-blank line - print and next cycle
  h             # blank line - save it in hold space
  :loop
  $b end        # last line - go to end
  n             # read next line in pattern space
  /^ *$/b loop  # blank line - loop to next one
  :end          # pattern space has non-blank line or last blank line
  /^ *$/{p;b}   # last blank line: print and exit
  H;x;p         # non-blank line: print hold + pattern space and next cycle
'
1
27.01.2020, 19:50

Опубликованные решения показались мне немного загадочными. Вот решение в Python 3.6:

#!/usr/bin/env python3

from pathlib import Path                                                                                                                                                              
import sys                                                                                                                                                                            
import fileinput                                                                                                                                                                      


def remove_multiple_blank_lines_from_file(path, strip_right=True): 
    non_blank_lines_out_of_two_last_lines = [True, True] 
    for line in fileinput.input(str(path), inplace=True): 
        non_blank_lines_out_of_two_last_lines.pop(0) 
        non_blank_lines_out_of_two_last_lines.append(bool(line.strip())) 
        if sum(non_blank_lines_out_of_two_last_lines) > 0: 
            line_to_write = line.rstrip() + '\n' if strip_right else line 
            sys.stdout.write(line_to_write)


def remove_multiple_blank_lines_by_glob(rglob='*', path=Path('.'), strip_right=True): 
    for p in path.rglob(rglob): 
        if p.is_file(): 
            try:
                remove_multiple_blank_lines_from_file(p, strip_right=strip_right)
            except Exception as e:
                print(f"File '{p}' was not processed due the error: {e}")


if __name__ == '__main__':
    remove_multiple_blank_lines_by_glob(sys.argv[1], Path(sys.argv[2]), next(iter(sys.argv[3:]), None) == '--strip-right')

Вы можете вызывать функции из интерпретатора или запускать их из оболочки, например:

$./remove_multiple_lines.py '*' /tmp/ --strip-right
0
27.01.2020, 19:50

Теги

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