Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

На главную -> MyLDP -> Тематический каталог -> Работа в консоли Linux

Peter Leung, "Командная строка: маленькие хитрости от Linux Commando"

Выбираем нужные строки из файла с помощью sed

Оригинал: Using sed to extract lines in a text file
Автор: Peter Leung
Дата: 22 марта 2008
Свободный перевод: Алексей Дмитриев
Дата перевода: 22 июля 2010

Тому, кто пишет много скриптов bash, часто приходится выбирать нужные строки из текста, например готовые блоки кода. Вчера я как раз должен был извлечь первую строку из файла, назовем его somefile.txt.

$ cat somefile.txt
Line 1
Line 2
Line 3
Line 4

Это очень просто сделать при помощи команды head:

$ head -1 somefile.txt
Line 1

Для более сложных задач, например, извлечь вторую и третью строки из того же файла, команда head не подходит.

Давайте попробуем команду sed ≈ редактор потока (STream Editor).

Моя первая попытка применить команду p (print) оказалась неудачной:

$ sed 1p somefile.txt
Line 1
Line 1
Line 2
Line 3
Line 4

Обратите внимание, что редактор печатает весь файл, причем указанную первую строку печатает дважды. Почему? По умолчанию редактор перепечатывает на стандартный вывод каждую строку вводимого файла. Четко заданная команда 1p приказывает печатать первую строку. В итоге первая строка дублируется.

Чтобы этого не происходило нужно подавить дефолтный вывод при помощи опции -n, чтобы на выводе был только результат команды 1p:

$ sed -n 1p somefile.txt
Line 1

Можно пойти другим путем и удалить из файла все строки, кроме первой:

$ sed '1!d' somefile.txt
Line 1

где '1!d' означает: если строка не является первой (!), то подлежит удалению. Обратите внимания на кавычки (одинарные). Они совершенно необходимы, так как без них конструкция 1!d вызовет последнюю запускавшуюся в шелле команду, начинающуюся с буквы d.

Для извлечения нескольких строк, скажем, со второй по четвертую, можно поступить одним из следующих способов:

  • $ sed -n 2,4p somefile.txt
  • $ sed '2,4!d' somefile.txt

Интервал обозначается через запятую включительно.

А если строки не идут друг за другом, например, с первой по вторую и еще четвертую?

$ sed -n -e 1,2p -e 4p somefile.txt

Line 1
Line 2
Line 4

Если вам известны иные способы выбирать нужные строки из файлов, сообщите, пожалуйста, в комментариях.

Послесловие переводчика:

И сообщили!

Блестящий пример нестандартного подхода продемонстрировал в комментариях к этой статье некий Chris:

Если я хочу извлечь пятую строку файла, то делаю так:
$ head -n 5 имя_файла | tail -n 1

А правда, здорово! И никаких заумных команд не надо с их километровыми манами. Кстати так и нужные блоки подряд идущих строк можно извлекать...