Распечатать определенную часть в выводе


11

Давайте предположим, что есть такая команда:

cat /boot/config-3.19.0-32-generic | grep CONFIG_ARCH_DEFCONFIG

Вывод как таковой:

CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"

Теперь мой вопрос: Есть ли какая - либо команда , которые будут печатать только то , что находится внутри кавычек, то есть " "?

И не могли бы вы немного объяснить команду? Спасибо! заранее, авансом.


5
Обратите внимание, что использование catв трубе почти всегда является пустой тратой ресурсов (AKA UUOC ); grepможет уже читать свои входные данные из файла (то есть, grep CONFIG_ARCH_DEFCONFIG /boot/config-3.19.0-32-genericделает то же самое, но 1. Это короче 2. Это проще для понимания 3. Это не разветвление дополнительной оболочки и дополнительного процесса). В 99% случаев использование cat в начале канала без объединения нескольких файлов просто вредно. :)
Кос

@kos - Спасибо! Не знал этого, так как я только начал использовать Linux. Буду иметь в виду.
Рафаэль

Np! Я оставляю свой комментарий выше для других людей, которые натыкаются на этот вопрос.
Кос

Первоначальный cat, хотя и бесполезный в этом случае, в будущем упростит редактирование всей строки команд на случай, если вы захотите что-то изменить / добавить / удалить позже, возможно, trили cut, и т. Д., Не нужно будет искать и перемещать имя файла убедитесь, что другая команда его поддерживает, найдите, куда ее поместить и т. д. А для небольшого тестового файла он добавляет только 0,002 с. (Я, вероятно, потратил больше времени, набирая это, чемcat
сэкономлю

1
@ Xen2050 почему catтут помощь? Вы можете сделать grep foo file | trили ... | cutтак же легко, как cat file | tr | grep .... catПросто добавляет дополнительные пять символов, дополнительные трубы и дополнительный вызов программы и не упрощает ничего.
тердон

Ответы:


15

Да, вы можете сделать это. Ваша команда будет:

cat /boot/config-3.19.0-32-generic | grep CONFIG_ARCH_DEFCONFIG | awk -F'"' '{print $2}'

который вернул бы только:

arch/x86/configs/x86_64_defconfig

Команда awkиспользует разделители полей с -Fкомандой, и чтобы установить для нее двойные кавычки, вы вводите ее с одинарными кавычками, как вокруг -F'"'. Затем он '{print $2}'сообщает awk распечатать второй набор после разделителя полей.

Надеюсь это поможет!


14
@Terrance, в данном случае это бесполезное использование catи grep. Вы можете заменить catи grepрасстаться с awk -F'"' '/CONFIG_ARCH_DEFCONFIG/{print $2}' /boot/config-3.19.0-32-generic . Меньше водопровода, позволяя AWK выполнять всю работу, на которую она более чем способна
Сергей Колодяжный

Согласитесь с @Serg
Tung Tran

@Serg Нет проблем. Я понимаю, что вы говорите. Я только добавил к его первоначальной команде, добавив к ней awkкоманду. =)
Терренс

11

Вы можете сделать это с помощью одной grepкоманды:

grep -Po '^CONFIG_ARCH_DEFCONFIG="\K[^"]*' /boot/config-3.19.0-32-generic

Или (немного дольше и более обидно):

grep -Po '^CONFIG_ARCH_DEFCONFIG="\K.*?(?=")' /boot/config-3.19.0-32-generic
  • -P: указывает grepинтерпретировать шаблон как PCRE (регулярное выражение, совместимое с Perl);
  • -o: говорит grepраспечатать только совпадение;
  • ^CONFIG_ARCH_DEFCONFIG=": соответствует CONFIG_ARCH_DEFCONFIG="строке в начале строки;
  • \K: отбрасывает ранее подобранную подстроку;

# 1:

  • [^"]*: соответствует любому количеству любого символа нет "(жадно).

# 2:

  • .*?: соответствует любому числу любого символа (лениво);
  • (?="): lookahead (утверждение нулевой длины, оно не соответствует ни одному символу); соответствует, если следующий символ является ".
% grep -Po '^CONFIG_ARCH_DEFCONFIG="\K[^"]*' /boot/config-4.2.0-16-generic
arch/x86/configs/x86_64_defconfig
% grep -Po '^CONFIG_ARCH_DEFCONFIG="\K.*?(?=")' /boot/config-4.2.0-16-generic
arch/x86/configs/x86_64_defconfig

Я люблю учиться более чем одним способом, чтобы достичь тех же результатов. Отличный ответ! =)
Терренс

10

Есть много способов снять кожу с этой кошки, вот sedспособ:

sed -nr 's/^CONFIG_ARCH_DEFCONFIG="([^"]+)"$/\1/p' /boot/config-3.19.0-32-generic

Здесь мы сопоставляем строку и получаем желаемую часть, то есть часть в двойных кавычках ( ([^"]+)), а затем заменяем всю строку только захваченной группой ( \1).

Пример:

% sed -nr 's/^CONFIG_ARCH_DEFCONFIG="([^"]+)"$/\1/p' /boot/config-3.13.0-32-generic
arch/x86/configs/x86_64_defconfig

10

Что нет perl?

grep CONFIG_ARCH_DEFCONFIG /boot/config-3.19.0-32-generic | 
    perl -pe 's/.*?"([^"]*).*/$1/'

perlБудет -pРинт каждой строки после применения сценария дается -e. s/foo/bar/Заменит fooс bar. Закономерности в скобках «захвачены» и могут быть отнесены к $1, $2... $Nгде $1это первая картина в плен, $2второй и т.д. регулярное выражение будет искать все до первой кавычки ( .*?"), а затем захватить 0 или более Непро- "символов ( [^"]*) а потом все остальное. Все это заменено захваченным рисунком.

Вы также можете оставить шаблон, соответствующий perl:

perl -ne 's/.*CONFIG_ARCH_DEFCONFIG="([^"]*).*/$1/ && print' /boot/config-3.19.0-32-generic

2
Я знал, что вы присоединитесь в какой-то момент: P +1
heemayl

тогда я бы сделал код на Python ..
Avinash Raj

with open('/boot/config-3.19.0-32-generic') as f: for line in f: if line.startswith('CONFIG_ARCH_DEFCONFIG'): print line.split('"')[1]
Авинаш Радж

@AvinashRaj хорошие вещи, хотите опубликовать это, пожалуйста? Я также опубликовал один с регулярным выражением.
Сергей Колодяжный

8

Вот комбинация grepи cut, которая делает ту же работу.

$ grep "CONFIG_ARCH_DEFCONFIG" /boot/config-3.19.0-32-generic | cut -d"\"" -f2                                                
arch/x86/configs/x86_64_defconfig

Объяснение:

  • grep "CONFIG_ARCH_DEFCONFIG" /boot/config-3.19.0-32-genericэто та часть , которая находит строку, в стандартном синтаксисе ГРЭП: grep [OPTIONS] PATTERN [FILE...]. Выход идет по трубе на следующую ступень
  • cut -d"\"" -f2, Эта часть использует обрезку для обрезки текста, разделенного определенным разделителем (который указывается с -dфлагом). Мы должны избегать двойных кавычек с помощью обратной косой черты, чтобы оболочка позволяла использовать двойные кавычки в качестве одного из параметров cutкоманды, а не вводить их в саму оболочку. Теперь cutбудем рассматривать вывод , grepкак разделены "и разделить на три колонны, CONFIG_ARCH_DEFCONFIG, arch/x86/configs/x86_64_defconfigи пустое пространство. Строка, которая нам нужна, это второй столбец, это означает, что нам нужно использовать -f2флаг.

3

Так как я сейчас учусь, pythonздесь есть версия, использующая именно это.

#!/usr/bin/env python
import re

reg = re.compile('CONFIG_ARCH_DEFCONFIG')

with open("/boot/config-3.19.0-32-generic") as file :
   for line in file:
       if reg.match(line):
           print line.split('"')[1]

Образец прогона:

DIR:/TECH-BOOKS
skolodya@ubuntu:$ ./extractString.py                                           
arch/x86/configs/x86_64_defconfig

DIR:/TECH-BOOKS
skolodya@ubuntu:$ cat ./extractString.py                                       
#!/usr/bin/env python
import re

reg = re.compile('CONFIG_ARCH_DEFCONFIG')

with open("/boot/config-3.19.0-32-generic") as file :
   for line in file:
       if reg.match(line):
           print line.split('"')[1]

Отступы очень важны в Python.
Avinash Raj

1
Вам не нужно использовать regexd, просто используйте мой, т. Е. line.startswithПотому что re.matchон намного медленнее, чемstartswith
Avinash Raj
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.