J'ai un fichier prova.txt
comme celui-ci:
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4
extra1
extra2
bla
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
extra2
bla
bla
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131
et je dois passer de "Commencer à saisir ici" à la première ligne vierge. La sortie devrait être comme ceci:
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131
Comme vous pouvez le voir, les lignes après "Commencer à saisir ici" sont aléatoires, donc l'indicateur -A -B grep ne fonctionne pas:
cat prova.txt | grep "Start to grab from here" -A 15 | grep -B 15 "^$" > output.txt
Pouvez-vous m'aider à trouver un moyen de capturer la première ligne qui sera saisie (comme "Commencer à saisir à partir d'ici"), jusqu'à une ligne vierge. Je ne peux pas prédire combien de lignes aléatoires j'aurai après "Commencer à saisir à partir d'ici".
Toute solution compatible Unix est appréciée (grep, sed, awk est meilleur que perl ou similaire).
EDITED: après une brillante réponse de @ john1024, je voudrais savoir s'il est possible de:
1 ° trier le bloc (selon Commencer à saisir d'ici: 1 puis 1 puis 2)
2 ° supprimer 4 lignes (alphabétiquement aléatoires) fix1, fix2, fix3, fix4 mais sont toujours 4
3 ° supprimer éventuellement les dupes aléatoires, comme la commande sort -u
La sortie finale doit être comme ceci:
# fix lines removed - match 1 first time
Start to grab from here: 1
random1
random2
random3
random4
#fix lines removed - match 1 second time
Start to grab from here: 1
#random1 removed cause is a dupe
random22131
#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561
ou
# fix lines removed - match 1 first time and the second too
Start to grab from here: 1
random1
random2
random3
random4
#random1 removed cause is a dupe
random22131
#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561
La deuxième sortie est meilleure que la première. Une autre magie de commande unix est nécessaire.
la source
Réponses:
Utiliser awk
Essayer:
/Start to grab/,/^$/
définit une plage. Il commence par n'importe quelle ligne qui correspondStart to grab
et se termine par la première ligne vide^$
, qui suit.Utilisation de sed
Avec une logique très similaire:
-n
dit à sed de ne rien imprimer à moins que nous ne le lui demandions explicitement./Start to grab/,/^$/p
lui indique d'imprimer toutes les lignes dans la plage définie par/Start to grab/,/^$/
.la source
Je poste une solution alternative car elle peut être utile à certains cas d'utilisation. Cette solution ne répond pas exactement aux exigences énoncées, pour la meilleure solution, voir la réponse de @ John1024.
Vous pouvez utiliser awk avec le séparateur d'enregistrements défini sur une chaîne vide, awk les interprétera comme des retours à la ligne vierges:
Cette version ne conserve pas les sauts de ligne vides dans la sortie. Il montrera également le contexte avant le match s'il est présent. Ce comportement peut être très utile lorsque vous recherchez quelque chose dans un fichier et que vous souhaitez voir le bloc délimité par la nouvelle ligne dont il fait partie, par exemple:
Par exemple, je trouve cela utile lors de la recherche de choses dans des
ini
fichiers.la source