Imprimer une pièce spécifique dans une sortie

11

Supposons qu'il existe une commande telle que:

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

La sortie est en tant que telle:

CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"

Maintenant, ma question est: Y a-t-il des commandes qui n'imprimeront que ce qui est à l'intérieur des virgules inversées, c'est-à-dire " "?

Et pourriez-vous expliquer un peu la commande? Je vous remercie! en avance.

Raphael
la source
5
Notez que l'utilisation catdans une pipe est presque toujours un gaspillage de ressources (AKA UUOC ); greppeut déjà lire son entrée à partir d'un fichier (c'est-à grep CONFIG_ARCH_DEFCONFIG /boot/config-3.19.0-32-generic- dire fait exactement la même chose, mais 1. Il est plus court 2. Il est plus facile à comprendre 3. Il ne crée pas de shell supplémentaire ni de processus supplémentaire). Dans 99% des cas, utiliser cat au début de la pipe sans concaténer plusieurs fichiers est juste dangereux. :)
kos
@kos - Thanx! Je ne le savais pas car je viens de commencer à utiliser Linux. Gardera cela à l'esprit.
Raphael
Np! Je laisse mon commentaire ci-dessus pour d'autres personnes tombant sur cette question.
kos
L'initiale cat, bien qu'inutile dans ce cas, rendrait l'édition de la ligne de commandes plus facile à l'avenir au cas où vous voudriez changer / ajouter / supprimer quelque chose plus tard, peut-être un trou cut, etc., pas besoin de trouver et déplacer le nom de fichier , assurez-vous que l'autre commande le prend en charge, trouvez où le mettre, etc. Et pour un petit fichier de test, il n'ajoute que 0,002 s. (J'ai probablement passé plus de temps à taper cela que je n'encat
aurais
1
@ Xen2050 pourquoi l' cataide ici? Vous pouvez le faire grep foo file | trou ... | cuttout aussi facilement que cat file | tr | grep .... Le catajoute simplement cinq caractères supplémentaires, un canal supplémentaire et un appel de programme supplémentaire et ne simplifie rien.
terdon

Réponses:

15

Oui, tu peux faire ça. Votre commande serait:

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

qui ne retournerait que:

arch/x86/configs/x86_64_defconfig

La awkcommande utilise des séparateurs de champs avec la -Fcommande, et pour la configurer pour utiliser des guillemets doubles, vous la tapez avec des guillemets simples autour d'elle comme -F'"'. Ensuite, le '{print $2}'awk indique d'imprimer le deuxième ensemble après le séparateur de champ.

J'espère que cela t'aides!

Terrance
la source
14
@Terrance, Dans ce cas, il s'agit d'une utilisation inutile de catet grep. Vous pouvez remplacer catet vous grepséparer awk -F'"' '/CONFIG_ARCH_DEFCONFIG/{print $2}' /boot/config-3.19.0-32-generic . Moins de plomberie, laissant AWK faire tout le travail, ce qu'elle est plus que capable de faire
Sergiy Kolodyazhnyy
D'accord avec @Serg
Tung Tran
@Serg Aucun problème. Je comprends ce que vous dites. Je ne faisais qu'ajouter à sa commande d'origine en ajoutant la awkcommande. =)
Terrance
11

Vous pouvez le faire avec une seule grepcommande:

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

Ou (un peu plus long et plus convulsé):

grep -Po '^CONFIG_ARCH_DEFCONFIG="\K.*?(?=")' /boot/config-3.19.0-32-generic
  • -P: indique grepd'interpréter le modèle comme un PCRE (expression régulière compatible Perl);
  • -o: indique grepde n'imprimer que la correspondance;
  • ^CONFIG_ARCH_DEFCONFIG=": correspond à une CONFIG_ARCH_DEFCONFIG="chaîne au début de la ligne;
  • \K: supprime la sous-chaîne précédemment mise en correspondance;

#1:

  • [^"]*: correspond à n'importe quel nombre de n'importe quel caractère non "(avec avidité).

# 2:

  • .*?: correspond à n'importe quel nombre de n'importe quel caractère (paresseusement);
  • (?="): lookahead (assertion de longueur nulle, elle ne correspond à aucun caractère); correspond si le caractère suivant est 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
la source
J'adore apprendre plus d'une façon d'obtenir les mêmes résultats. Très bonne réponse! =)
Terrance
10

Il existe de nombreuses façons de dépouiller ce chat, voici une sedfaçon:

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

Ici, nous faisons correspondre la ligne et capturons la partie souhaitée, c'est-à-dire la partie entre guillemets doubles ( ([^"]+)), puis nous remplaçons la ligne entière par le groupe capturé ( \1) uniquement.

Exemple:

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

Quoi, non perl?

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

Le perlva -pimprimer chaque ligne après avoir appliqué le script donné par -e. Le s/foo/bar/remplacera foopar bar. Les motifs entre parenthèses sont "capturés" et peuvent être appelés $1, $2... $N$1est le premier motif capturé, $2le deuxième etc. L'expression régulière recherchera tout jusqu'à la première citation ( .*?"), puis capturera 0 ou plusieurs "caractères non ( [^"]*) puis tout le reste. Le tout est remplacé par le motif capturé.

Vous pouvez également laisser le motif correspondant à perl:

perl -ne 's/.*CONFIG_ARCH_DEFCONFIG="([^"]*).*/$1/ && print' /boot/config-3.19.0-32-generic
terdon
la source
2
Je savais que vous vous
joindriez
alors je produirais un code 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 bonnes choses, veuillez poster ceci s'il vous plaît? J'en ai aussi publié un avec regex.
Sergiy Kolodyazhnyy
8

Voici une combinaison de grepet cutqui fait le même travail.

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

Explication:

  • grep "CONFIG_ARCH_DEFCONFIG" /boot/config-3.19.0-32-genericest la partie qui trouve la ligne, dans la syntaxe standard de grep: grep [OPTIONS] PATTERN [FILE...]. La sortie passe par le tuyau à l'étape suivante
  • cut -d"\"" -f2. Cette partie utilise du texte coupé à rogner séparé par un délimiteur spécifique (spécifié avec un -dindicateur). Nous devons échapper au guillemet double avec barre oblique inverse afin que le shell permette de prendre le guillemet double comme l'une des options de la cutcommande, plutôt que d'entrer dans le shell lui-même. Maintenant , cuttraitera de sortie grepcomme séparés par "et divisée en trois colonnes, CONFIG_ARCH_DEFCONFIG, arch/x86/configs/x86_64_defconfiget l' espace vide. La ligne dont nous avons besoin est la deuxième colonne, cela signifie que nous devons utiliser le -f2drapeau.
Sergiy Kolodyazhnyy
la source
3

Puisque j'apprends actuellement, pythonvoici une version utilisant exactement cela.

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

Exemple d'exécution:

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
la source
l'indentation est très7 très importante en python ..
Avinash Raj
1
Vous n'avez pas besoin d'aller pour regexd, utilisez simplement le mien c'est-à-dire, line.startswithcar il re.matchest beaucoup plus lent questartswith
Avinash Raj