Извлечь часть одной строки из файла с помощью sed


18

Я хочу прочитать одну часть одной строки из файла. Например:

POP3_SERVER_NAME = localhost

Я хочу только вернуться localhost, используя sed.

Этот текст находится на третьей строке. Я делаю это, чтобы извлечь строку:

sed -n '3p' installation.sh

Как извлечь только localhostчасть?

Ответы:


26

awk может быть лучшим инструментом здесь.

$ cat test.dat
LINE 1
LINE 2
POP3_SERVER_NAME = localhost

Поиск строк, которые содержат «POP3_SERVER_NAME»; напечатать последнее поле. Это не зависит от того, всегда ли POP3_SERVER_NAME находится в строке 3, что, вероятно, является хорошей идеей.

$ awk '/POP3_SERVER_NAME/{print $NF}' test.dat
localhost

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

$ awk '/^POP3_SERVER_NAME/{print $NF}' test.dat
localhost

Использование sed немного менее интуитивно понятно. (Спасибо, я знаю об иронии.) Адресуйте строку, которая содержит POP3_SERVER_NAME где угодно. Подставьте пустую строку для всего текста от начала строки до необязательного пробела после "=". Затем распечатайте.

sed -n -e '/POP3_SERVER_NAME/ s/.*\= *//p' test.dat

2
Команда awkхороша - но только если у вас есть пробелы вокруг =. Это не сработает POP3_SERVER_NAME=localhost.
Марсель Стёр

2
@Marcel, Вы можете изменить используемый разделитель awkс пробелов на что-то еще, используя -F. Например: -F "="будет использоваться =в качестве разделителя в том случае, если вы упомянули.
Mattpr

7

Замените pкоманду заменой, удаляющей ненужную часть строки.

sed -n '3 s/^[^=]*= *//p' installation.sh

Вы можете сопоставить строку по ключевому слову, а не по позиции.

sed -n 's/^ *POP3_SERVER_NAME *= *//p' installation.sh

6

Похоже, у вас есть файл конфигурации. То, что вы могли бы сделать, похоже на то, что Адам Симеон / СЛМ ​​предлагает:

sed -nr 's/[^=]+=\s*(.+)$/\1/p' filename

где [^=]исключает все «=» символы, +говорит один или более одного и того же типа характера, это с последующим фактическим =, \sлюбой пробел (включая вкладки \tи новых линий \n, \r\nи равнинных пространств «», а *значит ноль или более одного и того же типа , круглые скобки определяют, что находится внутри, чтобы поместить совпавшие символьные последовательности в замещающие заполнители \ 1, \ 2, ..., \ n, $означает конец строки. Это следует типичному шаблону замены:. s/.../.../modifiersПараметр командной строки -rобозначает расширенный синтаксис регулярных выражений (для удобства) и -nозначает, что ничего не выводится до или без явного запроса. pМодификатор печатает результат.

Вы можете сделать глобальный поиск с помощью gмодификатора, например:

sed -nr 's/[^=]+=\s*(.+)$/\1 /pg' filename  # note the space after \1

так что вы получите строку , разделенную ' '(может быть \n, \tили что там у вас) , которые вы можете обрабатывать легко.

Оба действительны при условии, что вашим значениям предшествует интервал символов уравнения до конца строки, и за ними не следуют комментарии или другие символы с семантикой, отклоняющейся от простого «значения».


Редактировать:

Я пока не могу комментировать посты других. Чтобы указать строку, просто передайте номер строки, в вашем случае 3, до sили перед инициализирующей кавычкой char (как в vim).

sed -nr '3s/[^=]+=\s*(.+)$/\1/p' filename

Пожалуйста, посмотрите на info sed. Например, 3.2 и 4.7 представляют для вас особый интерес.


5
echo "POP3_SERVER_NAME = localhost" | sed 's/.*= //'
localhost

Или, если у вас есть содержимое в файле:

sed 's/.*= //' somefile.txt
localhost

хорошо, но я читаю в своем файле так: sed -n '3p' installation.sh
Mercer

2
@Mercer - смотрите обновления, которые я добавил к ответу.
SLM

@ Adam Siemion - спасибо, но как указать номер строки?
Мерсер

4

Вы можете использовать команду вырезания, установив разделитель на «=», а затем напечатать второе поле следующим образом:

cut -d'=' -f2

3

Несколько способов сделать это, учитывая, что ваш файл называется foobar:

Укажите шаблон для поиска:

PAT=POP3_SERVER_NAME

Извлечь с помощью sed

sed -n "/$PAT/p" foobar | sed "s/$PAT = //"

Или используя sedиcut

sed -n "/$PAT/p" foobar | cut -d' ' -f3

2

Прелесть Linux / Unix в том, что обычно есть несколько способов сделать что-то. В случае операции существует как минимум четыре различных способа извлечь имя POP-сервера из файла:

  1. grep POP3_SERVER_NAME installation.sh | cut -d'=' -f2
  2. grep POP3_SERVER_NAME installation.sh | awk '{print $3}'
  3. grep POP3_SERVER_NAME installation.sh | sed 's/.*= //'
  4. sed -n 's/^.*POP3_SERVER_NAME = //p' installation.sh
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.