Cetak bagian tertentu dalam output

11

Mari kita anggap ada perintah seperti:

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

Outputnya seperti itu:

CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"

Sekarang, pertanyaan saya adalah: Apakah ada perintah yang hanya akan mencetak apa yang ada di dalam koma terbalik, yaitu " ",?

Dan bisakah Anda menjelaskan sedikit perintahnya? Terima kasih! terlebih dahulu.

Raphael
sumber
5
Perhatikan bahwa menggunakan catpipa hampir selalu merupakan pemborosan sumber daya (AKA UUOC ); grepdapat membaca inputnya dari file yang sudah (yaitu grep CONFIG_ARCH_DEFCONFIG /boot/config-3.19.0-32-genericmelakukan hal yang persis sama, tetapi 1. Ini lebih pendek 2. Lebih mudah untuk memahami 3. Tidak membayar shell tambahan dan proses tambahan). Dalam 99% kasus, menggunakan cat di awal pipa tanpa menyatukan beberapa file itu hanya berbahaya. :)
kos
@kos - Thanx! Tidak tahu itu karena saya baru saja mulai menggunakan linux. Akan mengingatnya.
Raphael
Np! Saya meninggalkan komentar saya di atas untuk orang lain menemukan pertanyaan ini.
kos
Yang pertama cat, meskipun tidak berguna dalam kasus ini, akan membuat pengeditan seluruh baris perintah lebih mudah di masa depan jika Anda ingin mengubah / menambah / menghapus sesuatu nanti, mungkin a tratau cut, dll, tidak harus menemukan & memindahkan nama file , pastikan perintah lain mendukungnya, temukan di mana meletakkannya, dll. Dan untuk file uji kecil itu hanya menambahkan 0,002s. (Saya mungkin menghabiskan lebih banyak waktu mengetik ini daripada yang pernah saya hemat seumur hidup untuk menghindari yang berlebihan cat)
Xen2050
1
@ Xen2050 mengapa catbantuan di sini? Anda dapat melakukannya grep foo file | tratau ... | cutsemudah itu cat file | tr | grep .... The cathanya menambah lima karakter tambahan, pipa tambahan dan panggilan Program tambahan dan tidak apa-apa menyederhanakan.
terdon

Jawaban:

15

Ya, Anda bisa melakukannya. Perintah Anda adalah:

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

yang hanya akan mengembalikan:

arch/x86/configs/x86_64_defconfig

The awkperintah menggunakan pemisah lapangan dengan -Fperintah, dan mengaturnya untuk menggunakan tanda kutip ganda, Anda ketik dengan tanda kutip tunggal di sekitarnya seperti -F'"'. Kemudian '{print $2}'memberitahu awk untuk mencetak set kedua setelah pemisah bidang.

Semoga ini membantu!

Terrance
sumber
14
@Terrance, Dalam hal ini penggunaan yang tidak berguna dari catdan grep. Anda dapat mengganti catdan grepberpisah dengan awk -F'"' '/CONFIG_ARCH_DEFCONFIG/{print $2}' /boot/config-3.19.0-32-generic . Lebih sedikit plumbing, membiarkan AWK melakukan semua pekerjaan, yang lebih dari mampu dilakukannya
Sergiy Kolodyazhnyy
Setuju dengan @Serg
Tung Tran
@Serg, Tidak masalah. Saya mengerti apa yang Anda katakan. Saya hanya menambahkan perintah aslinya dengan menambahkan awkperintah. =)
Terrance
11

Anda dapat melakukannya dengan satu grepperintah:

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

Atau (sedikit lebih lama dan lebih ramah):

grep -Po '^CONFIG_ARCH_DEFCONFIG="\K.*?(?=")' /boot/config-3.19.0-32-generic
  • -P: memberitahu grepuntuk menginterpretasikan pola sebagai PCRE (Perl Compatible Regular Expression);
  • -o: memberitahu grepuntuk mencetak hanya kecocokan;
  • ^CONFIG_ARCH_DEFCONFIG=": cocok dengan CONFIG_ARCH_DEFCONFIG="string di awal baris;
  • \K: membuang substring yang sebelumnya cocok;

# 1:

  • [^"]*: cocok dengan jumlah karakter apa pun yang tidak "(serakah).

# 2:

  • .*?: cocok dengan sejumlah karakter apa pun (malas);
  • (?="): lookahead (pernyataan nol panjang, tidak cocok dengan karakter apa pun); cocok jika karakter berikut adalah a ".
% 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
sumber
Saya suka belajar lebih dari satu cara untuk mencapai hasil yang sama. Jawaban bagus! =)
Terrance
10

Ada banyak cara untuk menguliti kucing ini, berikut sedcaranya:

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

Di sini kita mencocokkan garis dan menangkap bagian yang diinginkan yaitu bagian dalam tanda kutip ganda ( ([^"]+)) dan kemudian mengganti seluruh baris dengan kelompok yang ditangkap ( \1) saja.

Contoh:

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

Apa tidak perl?

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

Surat perlwasiat akan -pmembatalkan setiap baris setelah menerapkan skrip yang diberikan oleh -e. Surat s/foo/bar/wasiat akan diganti foodengan bar. Pola dalam tanda kurung "ditangkap" dan dapat disebut sebagai $1, $2... di $Nmana $1pola pertama ditangkap, $2yang kedua dll. Ekspresi reguler akan mencari semuanya sampai kutipan pertama ( .*?"), lalu ambil 0 atau lebih non- "karakter ( [^"]*) dan semuanya. Semuanya diganti dengan pola yang diambil.

Anda juga dapat membiarkan pencocokan pola ke perl:

perl -ne 's/.*CONFIG_ARCH_DEFCONFIG="([^"]*).*/$1/ && print' /boot/config-3.19.0-32-generic
terdon
sumber
2
Saya tahu Anda akan bergabung di beberapa titik: P +1
heemayl
maka saya akan menghasilkan kode 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 barang bagus, tolong kirimkan ini? Saya telah memposting satu dengan regex juga.
Sergiy Kolodyazhnyy
8

Berikut adalah kombinasi dari grepdan cut, yang melakukan pekerjaan yang sama.

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

Penjelasan:

  • grep "CONFIG_ARCH_DEFCONFIG" /boot/config-3.19.0-32-genericadalah bagian yang menemukan garis, dalam sintaks grep standar: grep [OPTIONS] PATTERN [FILE...]. Output melewati pipa ke tahap berikutnya
  • cut -d"\"" -f2. Bagian ini menggunakan memotong untuk memotong teks yang dipisahkan oleh pembatas khusus (yang ditentukan dengan -dbendera). Kita harus menghindari kutip ganda dengan backslash sehingga shell memungkinkan mengambil kutip ganda sebagai salah satu opsi untuk cutperintah, daripada input ke shell itu sendiri. Sekarang cutakan memperlakukan keluaran dari grepyang dipisahkan oleh "dan dibagi menjadi tiga kolom, CONFIG_ARCH_DEFCONFIG, arch/x86/configs/x86_64_defconfig, dan ruang kosong. Baris yang kita butuhkan adalah kolom kedua, itu artinya kita perlu menggunakan -f2flag.
Sergiy Kolodyazhnyy
sumber
3

Karena saya sedang belajar di pythonsini adalah versi menggunakan hal itu.

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

Contoh dijalankan:

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
sumber
lekukan ini sangat penting dalam python ..
Avinash Raj
1
Anda tidak perlu pergi untuk regexd, cukup gunakan milik saya yaitu, line.startswithkarena re.matchjauh lebih lambat daripadastartswith
Avinash Raj