Drucken Sie ein bestimmtes Teil in einer Ausgabe

11

Nehmen wir an, es gibt einen Befehl wie:

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

Die Ausgabe ist als solche:

CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"

Meine Frage lautet nun: Gibt es Befehle, die nur das drucken, was sich in den Anführungszeichen befindet, dh " "?

Und könnten Sie bitte den Befehl ein wenig erklären? Vielen Dank! im Voraus.

Raphael
quelle
5
Beachten Sie, dass die Verwendung catin einem Rohr fast immer eine Verschwendung von Ressourcen darstellt (AKA UUOC ). grepkann seine Eingabe bereits aus einer Datei lesen (dh grep CONFIG_ARCH_DEFCONFIG /boot/config-3.19.0-32-genericgenau das Gleiche tun, aber 1. Es ist kürzer 2. Es ist leichter zu verstehen 3. Es gibt keine zusätzliche Shell und keinen zusätzlichen Prozess). In 99% der Fälle ist die Verwendung von cat am Anfang der Pipe ohne Verkettung mehrerer Dateien nur schädlich. :)
Kos
@kos - Danke! Wusste das nicht, da ich gerade angefangen habe, Linux zu benutzen. Ich werde es mir merken.
Raphael
Np! Ich hinterlasse meinen obigen Kommentar für andere Leute, die über diese Frage stolpern.
Kos
Die Initiale cat, obwohl in diesem Fall nutzlos, würde das Bearbeiten der gesamten Befehlszeile in Zukunft erleichtern, falls Sie später etwas ändern / hinzufügen / entfernen möchten, vielleicht ein troder cutusw., müssen Sie den Dateinamen nicht finden und verschieben Stellen Sie sicher, dass der andere Befehl ihn unterstützt, finden Sie heraus, wo er abgelegt werden soll usw. Für eine kleine Testdatei werden nur 0,002 Sekunden hinzugefügt. (Ich habe wahrscheinlich mehr Zeit damit verbracht, dies zucat
tippen,
1
@ Xen2050 warum hilft das cathier? Sie können grep foo file | troder ... | cutgenauso einfach wie cat file | tr | grep .... Das catfügt nur zusätzliche fünf Zeichen, eine zusätzliche Pipe und einen zusätzlichen Programmaufruf hinzu und vereinfacht nichts.
Terdon

Antworten:

15

Ja, das kannst du machen. Ihr Befehl wäre:

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

was nur zurückkehren würde:

arch/x86/configs/x86_64_defconfig

Der awkBefehl verwendet Feldtrennzeichen mit dem -FBefehl. Um die Verwendung von doppelten Anführungszeichen festzulegen, geben Sie ihn wie folgt in einfache Anführungszeichen ein -F'"'. Dann '{print $2}'weist awk an, den zweiten Satz nach dem Feldtrennzeichen zu drucken.

Hoffe das hilft!

Terrance
quelle
14
@Terrance, In diesem Fall ist dies eine nutzlose Verwendung von catund grep. Sie könnten ersetzen catund greptrennen mit awk -F'"' '/CONFIG_ARCH_DEFCONFIG/{print $2}' /boot/config-3.19.0-32-generic . Weniger Klempnerarbeiten, damit AWK die ganze Arbeit erledigen kann, zu der es mehr als fähig ist
Sergiy Kolodyazhnyy
Stimmen Sie mit @Serg
Tung Tran
@Serg Keine Probleme. Ich verstehe was du sagst. Ich habe seinen ursprünglichen Befehl nur durch Hinzufügen des awkBefehls erweitert. =)
Terrance
11

Sie können dies mit einem einzigen grepBefehl tun :

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

Oder (etwas länger und konvultierter):

grep -Po '^CONFIG_ARCH_DEFCONFIG="\K.*?(?=")' /boot/config-3.19.0-32-generic
  • -P: weist grepan, das Muster als PCRE (Perl Compatible Regular Expression) zu interpretieren;
  • -o: weist grepan, nur die Übereinstimmung zu drucken;
  • ^CONFIG_ARCH_DEFCONFIG=": Entspricht einer CONFIG_ARCH_DEFCONFIG="Zeichenfolge am Zeilenanfang.
  • \K: verwirft den zuvor übereinstimmenden Teilstring;

# 1:

  • [^"]*: Entspricht einer beliebigen Anzahl von Zeichen, die nicht "(gierig) sind.

# 2:

  • .*?: Entspricht einer beliebigen Anzahl von Zeichen (träge);
  • (?="): lookahead (Behauptung ohne Länge, es passt zu keinem Zeichen); stimmt überein, wenn das folgende Zeichen a ist ".
% 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
kos
quelle
Ich liebe es, mehr als einen Weg zu lernen, um die gleichen Ergebnisse zu erzielen. Gute Antwort! =)
Terrance
10

Es gibt viele Möglichkeiten, diese Katze zu häuten. Hier ist eine sedMöglichkeit:

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

Hier passen wir die Zeile an und erfassen den gewünschten Teil, dh den Teil in doppelten Anführungszeichen ( ([^"]+)), und ersetzen dann die gesamte Zeile nur durch die erfasste Gruppe ( \1).

Beispiel:

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

Was, nein perl?

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

Das perlwird -pjede Zeile nach dem Anwenden des von -e. Das s/foo/bar/wird ersetzt foomit bar. Muster in Klammern „eingefangen“ und können als bezeichnet werden $1, $2... $Nwo $1ist das erste Muster erfaßt, $2die zweiten usw. Der regulären Ausdruck für alles aussehen wird , bis das erste Zitat ( .*?"), dann fängt 0 oder mehr Nicht - "Zeichen ( [^"]*) und dann alles andere. Das Ganze wird durch das erfasste Muster ersetzt.

Sie können die Musterübereinstimmung auch wie folgt belassen perl:

perl -ne 's/.*CONFIG_ARCH_DEFCONFIG="([^"]*).*/$1/ && print' /boot/config-3.19.0-32-generic
Terdon
quelle
2
Ich wusste, dass Sie irgendwann beitreten würden: P +1
heemayl
dann würde ich einen Python-Code produzieren ..
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]
Avinash Raj
@AvinashRaj gute Sachen, willst du das bitte posten? Ich habe auch eine mit Regex gepostet.
Sergiy Kolodyazhnyy
8

Hier ist eine Kombination von grepund cut, die den gleichen Job macht.

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

Erläuterung:

  • grep "CONFIG_ARCH_DEFCONFIG" /boot/config-3.19.0-32-genericist der Teil, der die Zeile in der Standard-Grep-Syntax findet : grep [OPTIONS] PATTERN [FILE...]. Der Ausgang geht durch die Leitung zur nächsten Stufe
  • cut -d"\"" -f2. In diesem Teil wird ausgeschnittener Text verwendet, der durch ein bestimmtes Trennzeichen (das mit einem -dFlag gekennzeichnet ist) getrennt ist. Wir müssen das doppelte Anführungszeichen mit Backslash umgehen, damit die Shell das doppelte Anführungszeichen als eine der Optionen für den cutBefehl verwendet, anstatt es in die Shell selbst einzugeben. Nun cutwird der Ausgang von behandeln grepals getrennt durch "und spaltete sich in drei Spalten CONFIG_ARCH_DEFCONFIG, arch/x86/configs/x86_64_defconfigund leeren Raum. Die Zeile, die wir benötigen, ist die zweite Spalte, dh wir müssen das -f2Flag verwenden.
Sergiy Kolodyazhnyy
quelle
3

Da ich gerade pythonhier lerne , ist eine Version, die genau das verwendet.

#!/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]

Probelauf:

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]
Sergiy Kolodyazhnyy
quelle
Einrückung ist sehr 7 sehr wichtig in Python ..
Avinash Raj
1
Sie müssen nicht für Regexd gehen, verwenden Sie einfach meine, dh, line.startswithweil re.matches viel langsamer ist alsstartswith
Avinash Raj