Роздрукуйте певну частину у висновку


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% випадків використання кота на початку труби без об'єднання декількох файлів це просто шкідливо. :)
kos

@kos - Дякую! Я не знав, що як тільки я почав використовувати Linux. Буде це мати на увазі.
Рафаель

Np! Я залишаю свій коментар вище для інших людей, що натикаються на це питання.
kos

Початковий cat, хоч і марний у цьому випадку, полегшить редагування всього рядка команд у майбутньому, якщо ви хочете щось змінити / додати / видалити пізніше, можливо, trабо cutтощо, не потрібно знаходити та переміщувати ім’я файлу , переконайтеся, що інша команда підтримує її, знайдіть куди її поставити тощо. А для невеликого тестового файлу він додає лише 0,002s. (Я, мабуть, витратив більше часу, набираючи це, ніж я коли-небудь заощаджував у житті, уникаючи зайвих cat)
Xen2050

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
@Терранс, У цьому випадку це марне використання 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 Compatible Regular Expression);
  • -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

то я б створив код пітона ..
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.