Ma sortie:
docker images | cut -d " " -f1 REPOSITORY jenkins/jenkins
Je voudrais simplement couper l'identifiant de l'image uniquement à partir de la sortie.
J'ai essayé d'utiliser cut
:
docker images REPOSITORY TAG IMAGE ID CREATED SIZE jenkins/jenkins lts 806f56c84444 8 days ago 703MB mongo latest 0da05d84b1fe 2 weeks ago 394MB
Le -f1
me donne juste les noms de référentiel, si j'utilise -f3
il a tendance à être vide. Comme le délimiteur n'est pas un espace unique, je ne vois pas comment obtenir la sortie souhaitée.
Pouvons-nous couper
en fonction des noms de champs?
I lu la documentation et je n'ai rien vu de pertinent. J'ai également vu qu'il existe un moyen d'y parvenir en utilisant sed / AWK que je suis encore en train de comprendre.
En attendant, y a-t-il un moyen plus simple d'y parvenir en utilisant la commande cut
?
Je suis nouveau sous Unix / Linux, comment puis-je déterminer lequel de Sed / AWK / Cut préférer?
6 Réponses :
Essayez ceci:
docker images | tr -s ' ' | cut -f3 -d' '
La commande tr -s ''
convertit plusieurs espaces en un seul et après coupure, vous pouvez saisir votre champ. Cela fonctionne bien si les valeurs de votre champ n'ont pas d'espaces.
Nan. Ça ne marche pas. images de docker | cut -f1,2,4 -d $ '\ t' REPOSITORY TAG IMAGE ID CREATED SIZE jenkins / jenkins lts 806f56c84444 il y a 9 jours 703MB mongo dernier 0da05d84b1fe il y a 2 semaines 394MB
images de docker | tr -s '' | cut -f3 -d "" Cela a fonctionné parfaitement
Votre entrée semble avoir une largeur fixe de 20 caractères pour chaque champ, vous pouvez donc utiliser la fonction FIELDWIDTHS
de gawk.
$ awk -v FIELDWIDTHS="20 20 20 20 20" '{ print $3 }' file IMAGE ID 806f56c84444 0da05d84b1fe $ $ awk -v FIELDWIDTHS="20 20 20 20 20" '{ printf "%20s%20s\n", $1, $3 }' file REPOSITORY IMAGE ID jenkins/jenkins 806f56c84444 mongo 0da05d84b1fe
De man gawk
:
Si la variable FIELDWIDTHS est définie sur une liste de nombres séparés par des espaces, chaque champ est censé avoir une largeur fixe et gawk divise l'enregistrement en utilisant les largeurs spécifiées. Chaque largeur de champ peut éventuellement être précédée d'une valeur séparée par deux-points spécifiant le nombre de caractères à ignorer avant le début du champ. La valeur de FS est ignorée. L'attribution d'une nouvelle valeur à FS ou FPAT remplace l'utilisation de FIELDWIDTHS.
Vous devez "presser" le remplissage de l'espace dans la sortie par défaut en un seul espace.
1 2
== 1-space-space-2
== Champ 1 avant le 1er espace, Champ entre le 1er et le 2ème espace, Champ 3 après le 2ème espace.
/ p>
couper -d '' -f1
==> '1'
cut -d '' -f2
==> '' champ vide entre le 1er et le 2ème délimiteur
couper -d '' -f3
==> '2'
Donc, dans votre cas, utilisez sed
pour remplacer les espaces consécutifs par 1:
images du docker | sed 's / * / / g' | couper -d "" -f1,3
Si la sortie est des largeurs de colonnes fixes, vous pouvez utiliser cette variante de coupe:
images du docker | couper -c1-20,41-60
Cela coupera les colonnes 41 à 60, où nous trouvons l'ID de l'image.
Si jamais la sortie utilise TAB
pour le remplissage, vous devez utiliser expand -tn
pour que la sortie soit constamment remplie d'espace, puis appliquez le cut -cx approprié, y
, par exemple (les nombres peuvent nécessiter un ajustement):
images du docker | développer -t 4 | couper -c1-20,41-60
Avec Modification de texte procédurale
c'est:
forEach line { if (contains ci "REPOSITORY") { remove } keepRange word 2 1 } removeEmptyLines // <- optional
Dans le cas général, évitez d'analyser les sorties destinées à la consommation humaine. De nombreux utilitaires modernes offrent une option pour produire une sortie dans un format standard comme JSON ou XML, ou même CSV (bien que cela soit moins strictement spécifié et existe dans plusieurs "dialectes").
docker
dans particulier a un --format code > option
qui vous permet de spécifier votre propre format de sortie:
import docker client = docker.from_env() for image in client.images.list(): print(image.id)
Si vous ne pouvez pas éviter d'écrire votre propre analyseur (en êtes-vous vraiment sûr !? Regardez à nouveau!) , cut
convient à la sortie avec un séparateur spécifique à un seul caractère, ou autrement une sortie assez régulière. Pour tout le reste, j'irais avec Awk. Prêt à l'emploi, il analyse les colonnes de séquences d'espaces, donc il fait précisément ce que vous demandez spécifiquement:
sed -n '2,$s/^[^ ]\+[ ]\+[^ ]\+[ ]\+\([^ ]\+\)[ ].*/\1/p'
( NR > 1
saute la première ligne, qui contient les en-têtes de colonne.)
Dans le cas de colonnes de largeur fixe, il vous permet d'extraire une chaîne par index:
XXX
... bien que vous puissiez le faire avec cut
aussi:
awk 'NR>1 { sub(/^([^[:space:]]*[[:space:]]+){2}/, ""); sub(/[[:space]].*/, ""); print }'
... mais remarquez que Docker peut ajuster la largeur des colonnes en fonction de la taille de votre écran!
Awk vous permet également d'écrire des extractions d'expressions régulières:
docker images | cut -c41-53
C'est là qu'il chevauche sed
:
docker images | awk 'NR>1 { print substr($0, 41, 12) }'
bien que sed
soit nettement moins lisible par l'homme, en particulier pour les scripts non triviaux. (C'est encore assez trivial.)
Si vous n'avez jamais utilisé de regex auparavant, ce qui précède semblera énigmatique, mais ce n'est vraiment pas très difficile à séparer. Nous recherchons des séquences de non-espaces (un champ dans une colonne) suivies de séquences d'espaces (un séparateur de colonne) - deux avant le champ ID et tout ce qui vient après, en commençant par le premier espace après la colonne ID. p>
Si vous voulez apprendre les scripts shell, vous devriez probablement aussi apprendre au moins les bases d'Awk (et une familiarité passagère avec sed
). Si vous voulez juste faire le travail et que vous n'êtes peut-être pas spécifiquement intéressé par l'apprentissage des outils U * x (même si vous devriez probablement l'être de toute façon!), Apprenez peut-être plutôt un langage de script moderne comme Python ou Ruby.
... Voici une bibliothèque docker
Python :
docker images | awk 'NR>1 { print $3 }'
Mais vraiment, dites simplement non à passer votre vie à écrire des analyseurs ad hoc pour des formats mal spécifiés avec des cas de coin interminables. J'en suis la preuve vivante: c'est ainsi que réside la folie.
Pouvons-nous couper
en fonction des noms de champs ? Non.
Comment puis-je déterminer lequel de Sed / AWK / Cut préférer ? YMMV. Pour cette entrée particulière où les champs sont séparés par deux espaces ou plus, en utilisant awk, vous pouvez définir le séparateur de champ sur "+"
(deux espaces ou plus), recherchez le nom de champ souhaité ( ID IMAGE
ci-dessous) et n'imprimez que ce champ particulier:
$ awk -F" +" '{if(f=="")for(i=1;i<=NF;i++)if($i=="IMAGE ID")f=i;if(f!="")print $f}' file
Sortie:
IMAGE ID 806f56c84444 0da05d84b1fe
En une seule ligne:
$ awk -F" +" ' # set field separator { if(f=="") # while we have not determined the desired field for(i=1;i<=NF;i++) # ... keep looking if($i=="IMAGE ID") f=i if(f!="") # once found print $f # start printing it }' file
docker rmi $ (images docker -f "dangling = true" -q)
La commande
docker
est livrée avec une option--format
pour vous permettre d'extraire exactement les champs dont vous avez besoin dans un format adapté à vos besoins. (Certes, l'utilisation de chaînes au format Go n'est pas immédiatement évidente pour nous, non-Go.)Avec l'astuce du tripleee:
docker images --format "{{.ID}}"
Et non,
cut
ne prend pas en charge l'extraction des champs par nom, bien que ce ne soit pas difficile à faire dans Awk non plus. Voir par exemple stackoverflow.com/questions/45608145/...Je pense à voter serré: les questions «quelle est la meilleure» sont généralement basées sur une opinion, et ne conviennent pas à ce Q&R.
Ces champs de largeur fixe ou colonnes ou colonnes séparées par des tabulations sont-ils séparés par plusieurs caractères vides ou que contient votre exemple d'entrée publié?
Comme la plupart des outils qui mettent en forme la sortie en colonnes pour l'écran,
docker
utilise l'équivalent du remplissage d'espace `printf``. Comme mentionné dans ma réponse, les dimensions des colonnes dépendent de la taille de votre écran.Par conséquent, même si les colonnes sont de largeur fixe, les largeurs ne peuvent pas toujours être prédites, ou vous devez utiliser des astuces comme mentir sur les dimensions de votre écran.