как sed\awk удалить все одинарные пустые строки?

В принципе можно даже как-то так:
awk '{if($0!="" || x=="")print $0} {if($0=="" && x=="" && y!="")print $0$0} {y=x;x=$0}' in.txt
не удалится только в начале и в конце одинарная пустая строка, если конечно они изначально будут, но это уже мелочи )
red
В принципе можно даже как-то так:
awk '{if($0!="" || x=="")print $0} {if($0=="" && x=="" && y!="")print $0$0} {y=x;x=$0}' in.txt
не удалится только в начале и в конце одинарная пустая строка, если конечно они изначально будут, но это уже мелочи )
Вот смотрю на эту конструкцию и удивляюсь ….
awk часто использую для вывода информации, несложной обработки выводимой информации, но даже и не подумал применить это в данном случае ….
Все-таки придется почитать awk и обратить пристальнее взор в его сторону ...
Для сравнения привожу конструкцию на bash - за красотой не гнался, важен был результат ... и, конечно, это понятнее ...
#!/bin/bash
#
count=0
cat ~/test.txt | (
    while read line ; do
        if [[ ${#line} = 0 ]]; then
           if [[ $count = 0 ]]; then
              count=$((count+1))
              elif [[ $count = 1 ]]; then
                    echo $line
                    echo $line
                    count=$((count+1))
               else
                    echo $line
                    count=$((count+1))
            fi
        else
             echo $line
             count=0
        fi
     done
)
exit 0
Ошибки не исчезают с опытом - они просто умнеют
vasek
... и, конечно, это понятнее ...
awk как и sed заточен на потоковую обработку данных, то есть разбор данных осуществляться последовательно с первого элемента до последнего в один проход.
В данном случае трудность задачи заключается в том что когда разбираешь текущий элемент то нужно учитывать значение не только предыдущих элементов но и значение впереди стоящего элемента.

можно записать чуть более понятную версию:
awk 'BEGIN {x=y=""} {if($0!="" || x=="")print $0} {if($0=="" && x=="" && y!="")print $0$0} {y=x;x=$0}' in.txt
BEGIN (здесь устанавливаются начальные параметры перед стартом обработки потока) я убрал так как в awk строковые переменные по умолчанию инициализируются пустой строкой.

{y=x;x=$0}
здесь мы говорим что после обработки текущей строки, а в awk это всегда $0, мы запоминаем её как предыдущую(x), в общем у нас будет:
y - предпредыдущая строка
x - предыдущая строка
$0 - текущая строка

{if($0!="" || x=="")print $0}
Здесь мы говорим что нужно печатать текущую строку(print $0) в том случае если она не пуста($0!="") или предыдущая строка пуста(x==""), а точнее когда предыдущая и текущая строки пусты то печатаем текущую пустую строку.
В общем если так и оставить то будут удалятся все одинарные пустые строки, а также одна пустая строка(первая) из пула пустых строк идущих подряд.

{if($0=="" && x=="" && y!="")print $0$0}
грязный хак )
если у нас идёт подряд несколько($0=="" && x=="") пустых строк и мы знаем что мы находимся в начале пула, точнее на второй(y!="") пустой строке, и беря во внимание что после первого условия({if($0!="" || x=="")print $0}) у нас удалялась первая пустая строка из пула, то мы просто удваиваем вторую пустую строку (здесь print $0$0 будет аналогично print "\n\n")
red, спасибо за разъяснением ...... просто никогда глубоко не вникал в awk ....... сейчас накачал кучу инфы, буду потихоньку вникать, правда не вижу пока для себя практического применения ........ вроде бы и нет таких задач под потоковый редактор
Ошибки не исчезают с опытом - они просто умнеют
vasek
правда не вижу пока для себя практического применения
везде где применяется sed можно применить awk, и как по мне, чем сложнее задача тем решение с помощью awk будет выглядеть понятнее чем с помощью sed.
 
Зарегистрироваться или войдите чтобы оставить сообщение.