Utilizzo di awk per uno script bash che definisce un "set minimo di pacchetti"
Vorrei scrivere uno script con i seguenti requisiti:
- in input, ottieni un elenco dei pacchetti disponibili tramite
apt. Lì potresti avere alcuni pacchetti che vengono installati automaticamente da altri pacchetti nell'elenco. - in output, fornire lo stesso elenco senza i pacchetti che dipendono da altri pacchetti nell'elenco.
In altri termini, voglio fare in bash ciò che l'utente Francois G ha fatto in questa risposta
Forse esiste già qualcosa del genere, ma a volte mi piace scrivere script per migliorare il mio scripting bash e anche per divertimento.
Nella mia mente, ho già progettato la sceneggiatura, ma ho un problema tecnico. Supponiamo di avere l'elenco delle dipendenze in questo formato (è il modo in cui lo apt-rdependsmetto):
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
Voglio estrarre il paragrafo relativo ad item-1es:
fixed-string substring-1-1
fixed-string substring-1-2
fixed-string substring-1-3
Non sono un awkesperto, ma penso che possa adattarsi ai miei scopi. Non sono in grado di "costruire" il comando corretto. A causa del fatto che item-2potrebbe non essere noto, ho provato:
# extract text between item-1 and the next line that starts without blank
$ awk '/item-1/,/^[A-Za-z0-9]/' deplist
item-1
ma si item-1adatta già alle condizioni ^[A-Za-z0-9], quindi non va bene. Inoltre, voglio escludere item-1e item-2dall'output.
Qual è il modo migliore per estrarre quella porzione di dati?
Risposte
Potresti fare qualcosa di "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
Come funziona:
impostato
p=0ogni volta che abbiniamo una linea che stelle con qualcosa di diverso dallo spazio bianco orizzontale (puoi usare il tuo originale leggermente più specifico^[A-Za-z0-9]qui)impostato
p=1se corrispondiamo al desiderato^itemstampare ogni volta
p==1
Essenzialmente "accendi la stampa quando abbiniamo l'elemento desiderato e spegnila quando abbiniamo qualsiasi altro elemento".
Avrai bisogno di un po 'di logica in più per saltare la riga corrispondente:
$ 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
Qui eseguiamo la stessa corrispondenza ma salviamo il risultato in variabile m; quindi imposta p=1quando mè vero (questa parte è identica a quella che avevamo prima); quindi stampiamo solo quando sia p==1e m==0ie salta la riga in cui si verifica la corrispondenza effettiva.