Как удалить верхние и последние непустые строки файла - PullRequest
1 голос
/ 15 октября 2019

Я хочу удалить верхнюю и последнюю непустую строку файла.

Пример:

cat test.txt

//blank_line
abc
def
xyz
//blank_line
qwe
mnp
//blank_line

Тогда вывод должен быть:

def
xyz
//blank_line
qwe

У меня естьпопытался с помощью команд

sed "$(awk '/./{line=NR} END{print line}' test.txt)d" test.txt

удалить последнюю непустую строку. Здесь есть две команды: (1) sed и (2) awk. Но я хочу сделать по одной команде.

Ответы [ 5 ]

3 голосов
/ 15 октября 2019

Это метод двойного прохода:

 awk '(NR==FNR) { if(NF) {t=FNR;if(!h) h=FNR}; next}
      (h<FNR && FNR<t)' file file

Целые числа h и t отслеживают голову и хвост. В этом случае пустые строки также могут содержать пробелы. Вы могли бы заменить if(NF) на if(length($0)==0), чтобы быть более строгим.

Этот читает все в память и делает простую замену в конце:

$ awk '{b=b RS $0}
       END{ sub(/^[[:blank:]\n]*[^\n]+\n/,"",b);
            sub(/\n[^\n]+[[:blank:]\n]*$,"",b);
            print b }' file
3 голосов
/ 15 октября 2019

Чтение всего файла в памяти одновременно с GNU sed для -E и -z:

$ sed -Ez 's/^\s*\S+\n//; s/\n\s*\S+\s*$/\n/' test.txt
def
xyz

qwe

или с GNU awk для мульти-символьного RS:

$ awk -v RS='^$' '{gsub(/^\s*\S+\n|\n\S+\s*$/,"")} 1' test.txt
def
xyz

qwe

ОбаИнструменты GNU принимают \ s и \ S в качестве сокращения для [[: space:]] и [^ [: space:]] соответственно, а GNU sed принимает non-POSIX-sed-standard \ n как значение новой строки.

2 голосов
/ 15 октября 2019

Однопроходный, быстрый и относительно эффективный в использовании подход с использованием буфера:

awk 'f {
    if(NF) {
        printf "%s",buf
        buf=""
    }
    buf=(buf $0 ORS)
    next
}
NF {
    f=1
}' file
0 голосов
/ 16 октября 2019

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

sed -E '0,/\S/d;H;$!d;x;s/.(.*)\n.*\S.*/\1/' file

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

Альтернатива:

sed '0,/\S/d' file | tac | sed '0,/\S/d'| tac
0 голосов
/ 15 октября 2019

вот версия решения @ kvantour для гольфа

$ awk 'NR==(n=FNR){e=!NF?e:n;b=!b?e:b}b<n&&n<e' file{,}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...