2010-08-18 3 views
96

Учитывая текстовый файл неизвестной длины, как я могу читать, например, все , но первые 2 строки файла? Я знаю, что tail даст мне последние N строк, но я не знаю, что N впереди времени.Что противоположно голове? Я хочу все, кроме первых N строк файла

Так что для файла

AAAA 
BBBB 
CCCC 
DDDD 
EEEE 

Я хочу

CCCC 
DDDD 
EEEE 

И для файла

AAAA 
BBBB 
CCCC 

Я бы получить только

CCCC 

ответ

149

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

Странно, моя страница человека не указала этот параметр, но он работает просто отлично - спасибо! –

+0

@ Николас: Странно, я полагал, что это будет стандартная документация, независимо от ОС. Я вытащил это из Cygwin внутри Windows, поэтому я не знаю, как он выглядит в разных дистрибутивах Linux. Рад, что это сработало. –

+0

@NicholasMTElliott [man7] (http://man7.org/linux/man-pages/man1/tail.1.html) перечисляет его как man-страницу Joe Enos, поэтому это может быть проблема с файловой версией –

0

Используйте это, предположив, что первый образец называется sample1.dat, затем tail --lines=3 sample1.dat, который будет печатать все строки от 3-й строки до последней строки.

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

+0

Но Николай не знает N заранее .... –

+0

@Jim: какая разница с твоей и моей? .... то же самое ....: o Я имел в виду два файла ввода данных с образцами данных в соответствии с его вопросом и показывая, как достичь того, что он искал .... – t0mm13b

+0

Хорошо ... тогда почему он попросил второй образец и показал результат, который он хотел, что это то, что я использовал 'tail -lines = - 1 '... конечно, вы можете полностью опустить имя файла и все еще можете действовать как трубка ... hmm – t0mm13b

4

tail -n +linecount filename начнет выпуск на линии linecount из filename, так tail -n +3 filename должны делать то, что вы хотите.

+0

Это не сработает в моей оболочке, но 'tail -n +17 filename' будет. Я использую bash/ubuntu LTS – isomorphismes

+1

@iso: Спасибо за хедз-ап - более старые версии 'tail' приняли синтаксис, который я использовал в своем первоначальном ответе, но теперь нужно использовать явный параметр' -n'. Я обновил свой ответ соответственно. –

15

Предполагая, что ваша версия хвоста поддерживает его, вы можете указать начало хвоста после X строк. В вашем случае вы бы сделали 2 + 1.

tail -n +3 

[[email protected] ~]$ tail -n +3 stack_overflow.txt 
CCCC 
DDDD 
EEEE 
0

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

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

Надеюсь, это поможет.

+1

Для этого требуется полный проход по файлу перед запуском хвоста. Если файл больше размера памяти, это будет очень неэффективно. Он не обрабатывает файлы менее двух строк. Он не обрабатывает размер файла, изменяющий размер между wc и хвостом. – janm

+2

@janm: С вами все в порядке. Другие ответы только лучше. Я чувствую смущение. :-p – NawaMan

11

Простое решение с использованием AWK:

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

Один из нас смущен. В этих вопросах говорится: «все, кроме первых двух строк файла». Как эта команда не отвечает требованиям? – janm

+4

'{print}' является действием по умолчанию и может быть опущено. – tripleee

-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" 
+0

Теперь это не соответствует требованиям. В этом вопросе говорится «все, кроме первых двух строк файла», и приводятся два примера, каждый из которых содержит один файл, где первые две строки пропущены, а оставшаяся часть файла отправляется на стандартный вывод. Это не то, что делает эта команда. – janm

+0

Да, я неправильно понял вопрос. думал, что он просит всех, кроме последних двух строк. – ghostdog74

7

Попробуйте sed 1,2d. При необходимости замените 2.

+0

работал так, как ожидалось .. поскольку количество строк после первых двух строк неизвестно. – kumarprd