Команда Awk для печати всех строк, за исключением последних трех строк

Вам нужна опция dns-nameservers в строфе iface eth0 inet static / etc / network / interfaces. Аргументом этого параметра должен быть IP-адрес какого-либо сервера имен. После добавления этой опции сделайте ifdown eth0 ; ifup eth0.

Также убедитесь, что пакет resolvconf установлен и что /etc/resolv.conf является символической ссылкой на ../run/resolvconf/resolv.conf; если это не так, запустите sudo dpkg-reconfigure resolvconf.

1
задан 2 June 2014 в 16:28

2 ответа

Для минимального использования памяти вы можете использовать круговой буфер:

awk 'NR>n{print A[NR%n]} {A[NR%n]=$0}' n=3 file

Используя оператор mod на номерах строк, мы имеем не более n записей массива.

Принимая пример n = 3:

В строке 1 NR%n равен 1, строка 2 производит 2, а строка 3 производит 0, а строка 4 снова оценивает 1.

Line 1 -> A[1]
Line 2 -> A[2]
Line 3 -> A[0]
Line 4 -> A[1]
Line 5 -> A[2]
...

Когда мы переходим к строке 4, A[NR%n] содержит содержимое строки 1. Таким образом, текст печатается, а A[NR%n] получает содержимое строки 4. Следующая строка (строка 5) печатает исходное содержимое строки 2 и так далее , пока мы не дойдем до конца. То, что остается незапечатанным, - это содержимое буфера, содержащего последние 3 строки ...

5
ответ дан 24 May 2018 в 07:04
  • 1
    работает. Было бы лучше, если вы немного объясните свою команду. – Avinash Raj 2 June 2014 в 17:30
  • 2
    Привет, @AvinashRaj: Добавлено объяснение .. – Scrutinizer 2 June 2014 в 17:41
  • 3
    Почему вы удалили это? Мне это нравится. – Oli♦ 2 June 2014 в 20:08
  • 4
    Привет @Oli, у меня создалось впечатление, что OP был доволен решением GNU head, которое доступно в Ubuntu, поэтому я думал, что мой пост не так уместен .. – Scrutinizer 2 June 2014 в 22:00

Вы также можете обработать файл дважды, чтобы не хранить что-либо в памяти:

awk '{if(NR==FNR){c++}else if(FNR<=c-3){print}}' file file

Трюк здесь - это тест NR==FNR. NR - текущий номер строки, а FNR - текущий номер текущей строки текущего файла. Если в качестве входных данных передано несколько файлов, FNR будет равно NR только при обработке первого файла. Таким образом, мы быстро получаем количество строк в первом файле и сохраняем его как c. Поскольку «два» файла на самом деле одинаковы, теперь мы знаем количество строк, которые мы хотим, поэтому мы печатаем только, если это один из них.

Хотя вы можете подумать, что это будет медленнее, чем другое подходы, это на самом деле быстрее, так как происходит не до обработки. Все делается с помощью внутренних инструментов awk (NR и FNR), кроме одного арифметического сравнения. Я тестировал файл 50 Мбайт с миллионом строк, созданных с помощью этой команды:

for i in {500000..1000000}; do 
    echo "The quick brown fox jumped over the lazy dog $i" >> file; 
done

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

$ for i in {1..10}; do ( 
    time awk '{if(NR==FNR){c++}else if(FNR<=c-3){print}}' file file > /dev/null ) 2>&1 | 
       grep -oP 'real.*?m\K[\d\.]+'; 
  done | awk '{k+=$1}END{print k/10" seconds"}'; 
0.4757 seconds

$  for i in {1..10}; do ( 
    time awk '{l[NR] = $0} END {for (i=1; i<=NR-3; i++) print l[i]}' file > /dev/null ) 2>&1 | 
        grep -oP 'real.*?m\K[\d\.]+'; 
   done | awk '{k+=$1}END{print k/10" seconds"}'; 
0.5347 seconds
2
ответ дан 24 May 2018 в 07:04
  • 1
    Я тоже думал о том, что вы могли бы использовать слегка встроенную в гольф версию awk 'NR!=FNR {FNR==1?c=NR:1} FNR<c-3' file file, используя встроенные функции NR,FNR вместо отдельного счета (c здесь - длина файла плюс одна ) и действие по умолчанию для печати. – steeldriver 3 June 2014 в 03:23
  • 2
    @steeldriver да, умный, спасибо! – terdon♦ 3 June 2014 в 04:54
  • 3
    Не оставляйте свой бенчмаркинг там . Круговой буфер работает так же быстро, как ваш, и мой второй подход (три переменные) на самом деле в два раза быстрее вашего. – Oli♦ 3 June 2014 в 12:41
  • 4
    @Oli, так оно и есть. Извините, так как я ожидал, что мой будет медленнее, я принял первое решение из принятого ответа и был приятно удивлен. – terdon♦ 3 June 2014 в 16:28
  • 5
    Умность использования FNR и NR – Sergiy Kolodyazhnyy 12 August 2015 в 15:40

Другие вопросы по тегам:

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