Как читать файл по строкам и печатать предыдущую строку, в которой файл содержит один токен

Например, мой файл выглядит так:

59 6 18 2014 169 7 14 2 7671912 7849744 201 4 60 6 19 2014 170 5 49 2 7671912 7849744 201 5 61 6 20 2014 171 6 8 2 7671912 7849744 201 6 62 6 23 2014 174 5 3 2 7671912 7849744 201 7 63 6 23 2014 174 7 17 2 7671912 7849744 201 8 64 6 24 2014 175 16 13 2 7671912 7849744 201 9 65 6 25 2014 176 8 20 2 7671912 7849744 201 10 10 1 1 49 6 16 2014 7 39 201 1 0 1043 <au_launchpad_back.gif> 201 gif <SIZE> 871 1 2 49 6 17 2014 13 15 201 1 0 1043 <au_launchpad_back.gif> 201 gif <SIZE> 871 1 3 49 6 18 2014 1 38 201 1 0 1043 <au_launchpad_back.gif> 201 gif <SIZE> 871 1 4 49 6 18 2014 7 14 201 1 0 1043 <au_launchpad_back.gif> 201 gif <SIZE> 871 1 5 49 6 19 2014 5 49 201 1 0 1043 <au_launchpad_back.gif> 201 gif <SIZE> 871 

Мне нужно напечатать предыдущую строку с одним токеном «10», который должен быть

 65 6 25 2014 176 8 20 2 7671912 7849744 201 10 

Как я могу это сделать?

Вы можете использовать awk :

 awk 'NF == 1 { print LAST } { LAST=$0 }' < datafile 

Это сохраняет каждую строку файла ( LAST=$0 ) по мере ее поступления, а когда строка имеет только одну запись ( NF == 1NF – количество токенов на линии, грубо говоря), она печатает сохраненную предыдущую строку ,

Если у вас есть только одно появление маркера, вы можете сделать это с помощью GNU grep и head :

 grep -x -B 1 10 file | head -n 1 

В -B 1 говорит grep печатать соответствующую строку и одну перед ней. С опцией -x grep 10 соответствует строкам, которые являются e x actly 10 (в отличие от 10 ). Наконец, head -n 1 печатает только первую из полученных строк.

СЕПГ

Вы можете использовать sed :

 sed -e '/^10$/{x;p;}' -e 'x;d' < datafile 

Объяснение:

Адрес /^10$/ соответствует строке, содержащей 10. Когда он совпадает, выполняется следующая серия команд, {x;p;} , которая обменивает ( x ) пространство удержания с пространством рисунка и затем печатает ( p ) пространство шаблонов.

Пространство удержания содержит предыдущую строку из-за остальной части скрипта. Для каждой строки файла обменивайте ( x ) пространство удержания с пространством рисунка, а затем удаляйте ( d ) все, что находится в пространстве шаблонов.

В отличие от первой команды, которая имеет префикс адреса, который приводит к тому, что он будет соответствовать только тогда, когда отображается 10 строк, эти команды не имеют префикса и, таким образом, соответствуют каждой строке файла. Конечным результатом является то, что мы продолжаем помещать последнюю строку в пространство удержания, а тот факт, что мы удаляем пространство шаблонов, означает, что нет выхода, кроме нашего явного вывода, когда мы видим 10.