Витягніть частину одного рядка з файлу з sed


18

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

POP3_SERVER_NAME = localhost

Я хочу повернутися лише localhostза допомогою sed.

Цей текст знаходиться у третьому рядку. Я роблю це для вилучення рядка:

sed -n '3p' installation.sh

Як витягти лише localhostчастину?

Відповіді:


26

Тут може бути кращим інструментом.

$ 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.
Marcel Stör

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

7

Замініть pкоманду на заміну, яка видаляє небажану частину рядка.

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

Ви можете скористатись рядком за ключовим словом, а не за позицією.

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

6

Схоже, у вас конфігураційний файл. Що ви можете зробити, схоже на те, що пропонує Адам Сімеон / slm:

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або перед початковою таблицею цитат (так само, як in 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 - див. Оновлення, які я додав у відповідь.
слм

@Adam Siemion - дякую, але як вказати номер рядка?
Мерсер

4

Ви можете скористатися командою cut, встановивши деліметр на '=', а потім надрукуйте друге поле так:

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.