Що протилежне голові? Я хочу всіх, крім перших N рядків файлу


142

Як подати текстовий файл невідомої довжини, як я можу прочитати, наприклад, усі, крім перших 2 рядків файлу? Я знаю tail, дасть мені останні N рядків, але я не знаю, що N випереджає час.

Так для файлу

AAAA
BBBB
CCCC
DDDD
EEEE

я хочу

CCCC
DDDD
EEEE

І для файлу

AAAA
BBBB
CCCC

Я б вийшов просто

CCCC

Відповіді:


211

tail --help дає наступне:

  -n, --lines=K            output the last K lines, instead of the last 10;
                           or use -n +K to output lines starting with the Kth

Отже, щоб відфільтрувати перші 2рядки, -n +3слід дати тобі вихід, який шукаєш (починаємо з 3-го).


2
Як не дивно, на моїй сторінці man не вказаний варіант, але він працює чудово - дякую!
Ніколас МТ Елліотт

@Nicholas: Дивно, я вважав, що це буде стандартна документація незалежно від ОС. Я витягнув це з Cygwin всередині Windows, тому я не знаю, як це виглядає в різних дистрибутивах Linux. Радий, що це спрацювало.
Джо Енос

@NicholasMTElliott man7 перераховує це як сторінку сторінки Джо Еноса, тому, ймовірно, це буде проблема з версією сторінки
Uli Köhler

@SteveJorgensen: я не розумію, на що йдеться у вашому коментарі; начебто ніхто не пропонує використовувати headдля цього?
ruakh

22

Якщо припустити, що ваша версія хвоста підтримує її, ви можете вказати запуск хвоста після X рядків. У вашому випадку ви зробили б 2 + 1.

tail -n +3

[mdemaria@oblivion ~]$ tail -n +3 stack_overflow.txt
CCCC
DDDD
EEEE

12

Просте рішення за допомогою awk:

awk 'NR > 2 { print }' file.name

Один із нас розгублений. У запитаннях сказано: "всі, крім перших 2 рядків файлу". Як ця команда не відповідає вимозі?
Янв

6
{ print }є типовою дією, і її можна опустити.
трійчатка

8

Спробуйте sed 1,2d. Замініть 2 за потребою.


працювали як очікувалося .. оскільки кількість рядків після перших 2 рядків невідома.
kumarprd

6

tail -n +linecount filenameпочнеться вихід на лінії linecountз filename, так tail -n +3 filename повинні робити те , що ви хочете.


Це не працює в моїй оболонці, але tail -n +17 filenameбуде. Я використовую bash / ubuntu LTS
ізоморфізми

2
@iso: Дякую за хед-ап - старіші версії tailприйнятого синтаксису, який я використовував у своїй оригінальній відповіді, але тепер потрібно використовувати явний -nваріант. Я відповідно оновив свою відповідь.
Джим Льюїс

0

Використовуйте це, припустивши, що перший зразок називається sample1.dat, tail --lines=3 sample1.datякий би надрукував усі рядки з 3-го рядка до останнього рядка.

Для другого зразка, припустимо, він називається sample2.dat, це було б, tail --lines=-1 sample2.datяке друкувало б останній рядок ...


@Jim: яка різниця з вашими та моїми? .... те ж саме ....: o Я мав на увазі два вхідних файли даних даних відповідно до його запитання та показував, як досягти того, що він шукав ... .
t0mm13b

Добре ... тоді чому він попросив другий зразок і показав той результат, який він хотів, і це те, що я використовував "хвіст - лінії = -1" ...... звичайно, ви можете повністю опустити ім'я файлу та його все ще може виступати в ролі труби ... хм
t0mm13b

@tommie: На жаль, забудь, що я сказав про труби ... Я, мабуть, думав про якусь іншу утиліту. Але моя думка полягала в тому, що одна команда, tail +3 anyfileдає бажані результати для загального випадку, тоді як tail --lines=Nвимагає знати N заздалегідь, щоб дати бажаний результат.
Джим Льюїс

@tommie: Але це tail... хіба це не повинно бути "знизу"? (Ба-дум ТІШ! Дякую, я буду тут увесь тиждень ...)
Джим Льюїс

0

Я дійсно не знаю, як це зробити лише з хвоста чи голови, але за допомогою wc -l(кількість рядків) та висловлювання башти, ви можете досягти цього.

tail -$(( $( wc -l $FILE | grep -Eo '[0-9]+' ) - 2 )) $FILE

Сподіваюся, це допомагає.


1
Для цього потрібен повний пропуск над файлом перед запуском хвоста. Якщо файл перевищує об'єм пам'яті, це буде дуже неефективно. Він не обробляє файли менше двох рядків. Він не обробляє розмір файлу, що змінюється між туалетом та хвостом.
janm

2
@janm: У вас все гаразд. Інші відповіді просто кращі. Мені соромно. :-p
NawaMan

-1

використовуючи awk, щоб отримати всі, крім останнього 2 рядка

awk 'FNR==NR{n=FNR}FNR<=n-3{print}' file file

awk, щоб отримати всі, крім перших 2 рядків

awk 'NR>2' file

АБО ви можете використовувати більше

more +2 file

або просто баш

#!/bin/bash

i=0
while read -r line
do
  [[ $i > 1 ]] && echo "$line"
  ((i++))
done <"file"

Тепер це не відповідає вимозі. Питання говорить "всі, крім перших двох рядків файлу", і наводить два приклади, кожен з яких має один файл, де перші два рядки пропускаються, а решта файлу надсилається до stdout. Це не те, що робить ця команда.
janm

так, я неправильно прочитав питання. думав, що він просить усіх, окрім двох останніх рядків.
ghostdog74
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.