Grep предпоследняя линия - PullRequest
0 голосов
/ 06 октября 2011

Как видно из заголовка, как я могу отфильтровать с помощью grep (или аналогичного инструмента bash) строку до последней строки файла (переменной длины)?

То есть показать все, КРОМЕпредпоследняя строка.

Спасибо

Ответы [ 4 ]

7 голосов
/ 06 октября 2011

Вы можете использовать комбинацию head и tail, например, вот так:

$ cat input 
one
two
three
HIDDEN
four
$ head -n -2 input ; tail -n 1 input 
one
two
three
four

Из coreutils head документация:

'- n k'
'--lines = k'
Вывести первые k строк.Однако, если k начинается с '-', выведите все, кроме последних k строк, каждого файла.Суффиксы множителя размера такие же, как и в опции -c.

Таким образом, часть head -n -2 удаляет все входные данные, кроме последних двух строк.

Это, к сожалению, не переносимо.(POSIX не допускает отрицательных значений в параметре -n.)

2 голосов
/ 06 октября 2011

grep не тот инструмент для этого. Вы можете использовать его как

# Get line count
count=$(wc -l <file)
# Subtract one
penultimate=$(expr $count - 1)
# Delete that line, i.e. print all other lines.
# This doesn't modify the file, just prints
# the requested lines to standard output.
sed "${penultimate}d" file

Bash имеет встроенные арифметические операторы, которые более элегантны, чем expr; но expr переносим на другие оболочки.

Вы также можете сделать это в чистом виде sed, но я не хочу об этом думать. В Perl или awk было бы легко напечатать предыдущую строку, а затем в EOF вывести последнюю строку.

Редактировать: Я думал о sed в конце концов.

sed -n '$!x;1!p' file

Более подробно; если мы не на последней строке ($), поменяйте пространство образца и пространство удержания (запомните текущую строку; получите предыдущую строку, если есть). Затем, если только это не первая строка, выведите все, что сейчас находится в пространстве шаблона (предыдущую строку, кроме случаев, когда мы находимся на последней строке).

0 голосов
/ 06 октября 2011

Использование ed:

printf '%s\n' H '$-1d' wq | ed -s file          # in-place file edit
printf '%s\n' H '$-1d' ',p'  wq | ed -s file    # write to stdout
0 голосов
/ 06 октября 2011

awk oneliner: (тест с последовательностью 10):

kent$  seq 10|awk '{a[NR]=$0}END{for(i=1;i<=NR;i++)if(i!=NR-1)print a[i]}'  
1
2
3
4
5
6
7
8
10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...