Wydrukuj określoną część na wydruku

11

Załóżmy, że istnieje takie polecenie, jak:

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

Dane wyjściowe są takie:

CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"

Moje pytanie brzmi: czy są jakieś polecenia, które wypisują tylko to, co jest w przecinku, tzn. " "?

Czy mógłbyś trochę wyjaśnić polecenie? Dziękuję Ci! z góry.

Raphael
źródło
5
Zauważ, że używanie catw potoku jest prawie zawsze marnotrawstwem zasobów (AKA UUOC ); greppotrafi już odczytać dane wejściowe z pliku (tzn. grep CONFIG_ARCH_DEFCONFIG /boot/config-3.19.0-32-genericrobi dokładnie to samo, ale 1. Jest krótszy 2. Łatwiej zrozumieć 3. Nie rozwidla dodatkowej powłoki i dodatkowego procesu). W 99% przypadków użycie cat na początku potoku bez łączenia wielu plików jest po prostu szkodliwe. :)
Kos
@kos - Thanx! Nie wiedziałem o tym, ponieważ właśnie zacząłem używać Linuksa. Będę o tym pamiętać.
Raphael,
Np! Zostawiam powyższy komentarz dla innych osób, które natknęły się na to pytanie.
Kos
Początkowy cat, choć w tym przypadku bezużyteczne, stałaby edycji całą linię poleceń łatwiejszych w przyszłości w przypadku, gdy chcesz zmienić / dodać / usunąć coś później, może tralbo cut, etc, nie trzeba znaleźć i przenieść pliku , upewnij się, że drugie polecenie go obsługuje, znajdź, gdzie go umieścić itp. A w przypadku małego pliku testowego dodaje tylko 0,002 s. (Prawdopodobnie spędziłem więcej czasu na pisaniu tego, niż kiedykolwiek zaoszczędzę w ciągu całego życia, unikając zbędnych cat)
Xen2050
1
@ Xen2050, dlaczego catpomoc tutaj? Możesz to zrobić grep foo file | trlub ... | cuttak łatwo, jak cat file | tr | grep .... Po catprostu dodaje dodatkowe pięć znaków, dodatkowy potok i dodatkowe wywołanie programu i niczego nie upraszcza.
terdon

Odpowiedzi:

15

Tak, możesz to zrobić. Twoje polecenie będzie:

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

które zwróci tylko:

arch/x86/configs/x86_64_defconfig

awkKomenda używa separatory pól z -Fpolecenia i ustawić go użyć cudzysłowia, wpisz ją w z pojedynczych cytatów wokół niego jak -F'"'. Następnie '{print $2}'mówi awk, aby wydrukował drugi zestaw po separatorze pól.

Mam nadzieję że to pomoże!

Terrance
źródło
14
@Terrance, W tym przypadku jest to bezużyteczne użycie cati grep. Możesz wymienić cati greprozdzielić awk -F'"' '/CONFIG_ARCH_DEFCONFIG/{print $2}' /boot/config-3.19.0-32-generic . Mniej hydrauliki, pozwalając AWK wykonać całą pracę, którą jest więcej niż w stanie wykonać
Sergiy Kolodyazhnyy,
Zgadzam się z @Serg
Tung Tran
@Serg Brak problemów. Rozumiem co mówisz. Dodałem tylko do jego pierwotnego polecenia, dodając awkpolecenie. =)
Terrance
11

Możesz to zrobić za pomocą jednego greppolecenia:

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

Lub (nieco dłużej i bardziej przekonująco):

grep -Po '^CONFIG_ARCH_DEFCONFIG="\K.*?(?=")' /boot/config-3.19.0-32-generic
  • -P: każe grepinterpretować wzorzec jako PCRE (wyrażenie regularne zgodne z Perl);
  • -o: mówi, grepaby wydrukować tylko dopasowanie;
  • ^CONFIG_ARCH_DEFCONFIG=": dopasowuje CONFIG_ARCH_DEFCONFIG="ciąg na początku linii;
  • \K: odrzuca poprzednio dopasowany podciąg;

# 1:

  • [^"]*: dopasowuje dowolną liczbę dowolnych znaków nie "(łapczywie).

# 2:

  • .*?: dopasowuje dowolną liczbę dowolnych znaków (leniwie);
  • (?="): lookahead (asercja zerowa, nie pasuje do żadnego znaku); pasuje, jeśli następujący znak to ".
% 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
źródło
Uwielbiam uczyć się więcej niż jednego sposobu na osiągnięcie tych samych rezultatów. Świetna odpowiedź! =)
Terrance,
10

Jest wiele sposobów na skórowanie tego kota, oto sedsposób:

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

Tutaj dopasowujemy linię i przechwytujemy pożądaną część, tj. Część w podwójnych cudzysłowach ( ([^"]+)), a następnie zastępujemy całą linię tylko przechwyconą grupą ( \1).

Przykład:

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

Co nie perl?

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

perlBędzie -prukuj każdy wiersz po zastosowaniu skryptu podane przez -e. s/foo/bar/Zastąpi fooz bar. Wzorce w nawiasach są „zrobione” i może być dalej $1, $2... $Ngdzie $1jest 1 wzór niewoli, $2drugi itp wyrażenie regularne będzie patrzeć na wszystko, aż pierwszy cytat ( .*?"), a następnie uchwycić 0 lub więcej innych niż "znaki ( [^"]*) i wszystko inne. Całość zastąpiono przechwyconym wzorem.

Możesz także pozostawić pasujący wzór do perl:

perl -ne 's/.*CONFIG_ARCH_DEFCONFIG="([^"]*).*/$1/ && print' /boot/config-3.19.0-32-generic
terdon
źródło
2
Wiedziałem, że dołączysz w pewnym momencie: P +1
heemayl
następnie wygenerowałbym kod 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]
Avinash Raj,
@AvinashRaj dobre rzeczy, czy chcesz to opublikować, proszę? Opublikowałem też jedną z wyrażeniem regularnym.
Sergiy Kolodyazhnyy
8

Oto kombinacja grepi cut, który wykonuje tę samą pracę.

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

Wyjaśnienie:

  • grep "CONFIG_ARCH_DEFCONFIG" /boot/config-3.19.0-32-genericJest to część, która znajduje się linii w standardzie składni grep: grep [OPTIONS] PATTERN [FILE...]. Wyjście przechodzi przez potok do następnego etapu
  • cut -d"\"" -f2. W tej części zastosowano wycięcie do przycięcia tekstu oddzielonego określonym separatorem (który jest oznaczony -dflagą). Musimy uciec od podwójnego cudzysłowu odwrotnym ukośnikiem, aby powłoka pozwalała na przyjmowanie podwójnego cudzysłowu jako jednej z opcji cutpolecenia, zamiast wprowadzania danych do samej powłoki. Teraz cutbędzie traktować wyjście z grepjako oddzielone "i podzielone na trzy kolumny, CONFIG_ARCH_DEFCONFIG, arch/x86/configs/x86_64_defconfigi pustej przestrzeni. Linia, której potrzebujemy, to druga kolumna, co oznacza, że ​​musimy użyć -f2flagi.
Sergiy Kolodyazhnyy
źródło
3

Ponieważ obecnie uczę się pythontutaj, jest wersja korzystająca właśnie z tego.

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

Przykładowy przebieg:

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
źródło
wcięcie jest bardzo ważne w Pythonie ..
Avinash Raj
1
Nie musisz wybierać wyrażeń regularnych, po prostu użyj mojego, tj., line.startswithPonieważ re.matchjest znacznie wolniejszy niżstartswith
Avinash Raj