Utilisation de awk pour un script bash qui définit un «ensemble de packages minimum»
Je souhaite écrire un script avec les exigences suivantes:
- en entrée, obtenez une liste des packages disponibles via
apt. Vous y trouverez peut-être des packages qui sont automatiquement installés par d'autres packages de la liste. - en sortie, fournissez la même liste sans les packages qui dépendent des autres packages de la liste.
En d'autres termes, je veux faire en bash ce que l'utilisateur François G a fait dans cette réponse
Peut-être que quelque chose comme ça existe déjà, mais parfois j'aime écrire des scripts pour améliorer mes scripts bash et aussi pour le plaisir.
Dans mon esprit, j'ai déjà conçu le script, mais j'ai un problème technique. Supposons que j'ai la liste de dépendances dans ce format (c'est la façon dont apt-rdependson le dit):
useless-line-1
useless-line-2
useless-line-3
item-1
fixed-string substring-1-1
fixed-string substring-1-2
fixed-string substring-1-3
item-2
fixed-string substring-2-1
fixed-string substring-2-2
item-3
item-4
fixed-string substring-4-1
fixed-string substring-4-2
fixed-string substring-4-3
fixed-string substring-4-4
Je veux extraire le paragraphe relatif à item-1ie:
fixed-string substring-1-1
fixed-string substring-1-2
fixed-string substring-1-3
Je ne suis pas un awkexpert, mais je pense que cela peut convenir à mes objectifs. Je ne parviens pas à "créer" la commande correcte. En raison du fait que item-2cela n'est peut-être pas connu, j'ai essayé:
# extract text between item-1 and the next line that starts without blank
$ awk '/item-1/,/^[A-Za-z0-9]/' deplist
item-1
mais item-1correspond déjà à la condition ^[A-Za-z0-9], donc ce n'est pas bon. De plus, je veux exclure item-1et item-2de la sortie.
Quelle est la meilleure façon d'extraire cette partie des données?
Réponses
Vous pourriez faire quelque chose de "stateful" ex.
$ awk -v item='item-1' '$0 !~ /^[[:blank:]]/{p=0} $0 ~ "^" item {p=1} p' deplist
item-1
fixed-string substring-1-1
fixed-string substring-1-2
fixed-string substring-1-3
Comment ça marche:
défini
p=0chaque fois que nous associons une ligne qui étoile avec autre chose qu'un espace blanc horizontal (vous pouvez utiliser votre original un peu plus spécifique^[A-Za-z0-9]ici)défini
p=1si nous correspondons au^itemimprimer à chaque fois
p==1
Essentiellement, "activer l'impression lorsque nous correspondons à l'élément souhaité et la désactiver lorsque nous correspondons à un autre élément".
Vous aurez besoin d'un peu de logique supplémentaire pour ignorer la ligne correspondante:
$ awk -v item='item-1' '
$0 !~ /^[[:blank:]]/{p=0} {m = $0 ~ "^" item ? 1 : 0} m {p=1} p && !m
' deplist
fixed-string substring-1-1
fixed-string substring-1-2
fixed-string substring-1-3
Ici, nous effectuons la même correspondance mais enregistrons le résultat dans la variable m; puis définissez p=1quand mest vrai (cette partie est identique à ce que nous avions auparavant); nous n'imprimons alors que lorsque les deux p==1et m==0ie sautons la ligne où la correspondance réelle se produit.