grep --before-context 5
affiche 5 lignes avant le match.
Je veux tout montrer avant le match.
Faire grep --before-context 99999999
fonctionnerait mais ce n'est pas très ... professionnel.
Comment afficher tout le fichier jusqu'au match?
Sed est mieux pour ça.
Faites juste:
sed '/PATTERN/q' FILE
Cela fonctionne comme ceci:
Pour chaque ligne, nous regardons si elle correspond à /PATTERN
:
C'est la solution la plus efficace, car dès qu'elle voit PATTERN
, elle se ferme. Sans q
, sed continuerait à lire le reste du fichier et ne ferait rien avec. Pour les gros fichiers, cela peut faire la différence.
Cette astuce peut également être utilisée pour émuler head
:
sed 10q FILE
sed
peut remplacer la plupart des fonctionnalités de grep.
sed -n '1,/<pattern>/ p' <file>
Cela signifie imprimer à partir de la première ligne jusqu'à ce que le motif corresponde.
Quelques exemples de gamme
sed -n '/<pattern>/,$ p' <file> # from pattern to end of file
sed -n '/<pattern1>/,/<pattern2>/ p' <file> # from pattern1 to pattern2
imprimer jusqu'au match inclus:
awk '{print} /pattern/ {exit}' filename
sed '/pattern/q' filename
imprimer jusqu'à MAIS NON compris le match:
awk '/pattern/ {exit} {print}' filename
sed '/pattern/Q' filename
Pour les personnes qui choisissent de ne se souvenir que des outils de base dans le travail quotidien et qui souhaitent accepter des solutions moins élégantes et moins efficaces:
head -n $(grep -n pattern filename | cut -d: -f1) filename
Si cette commande est destinée à un script, je chercherai des solutions plus élégantes (et éventuellement efficaces). S'il s'agit d'une commande unique ou d'un script à jeter, je m'en fiche.
Ajout à la réponse de Mikel ci-dessus ...
Pour imprimer toutes les lignes jusqu'à la première ligne de FILE
contenant PATTERN
, sans inclure , essayez:
sed '/.*PATTERN.*/{s///;q;}' FILE
Cela correspond à la ligne entière contenant le modèle, le remplace par une ligne vierge, puis se ferme sans traiter le reste du fichier.
Post-script:
La manière la plus simple/la plus claire à laquelle j'ai pu penser pour empêcher l'impression d'une nouvelle ligne supplémentaire à la fin (sans impliquer un autre outil), était de relancer sed et de supprimer la nouvelle ligne finale:
sed '/.*PATTERN.*/{s///;q;}' FILE | sed '$d'
... et puisque nous supprimons maintenant cette ligne de toute façon, notre travail précédent est redondant et nous pouvons simplifier pour:
sed '/PATTERN/q' FILE | sed '$d'
Les méthodes GNU grep
pures suivantes ne sont pas efficaces.
Recherchez tout jusqu'à la première instance de la chaîne " foo " dans barre de fichier , en utilisant trois grep
s:
grep -m 1 -B $(grep -n -m 1 foo bar | grep -o '^[0-9]*') foo bar
Correspondance avec la dernière instance de " foo ":
grep -oPz "(?s)[^\n]*${s}.*?\n.*?foo.*?\n" bar
Remarque: les détails sur le dernier grep
peuvent être trouvés dans: Regex (grep) pour la recherche multi-lignes nécessaire .
Vous pouvez également utiliser l'un des éléments suivants
tac ./test | grep -B $(cat ./test | wc -l) -m 1 'pattern'|tac
ou
tac ./test |head -n $(tac ./test | grep -n 'pattern' | cut -d: -f1 | head -n 1)|tac
ou
tac ./test |sed ':a;N;$!ba;s/\n/'"pattern"'/g' | sed 's/'"patternpattern"'/\n/g'|head -n 1|sed 's/'"pattern"'/\n/g'|tac
La première option est très similaire à ce que l'OP a suggéré seulement, elle s'assure de montrer suffisamment de lignes avant le contexte en comptant les lignes dans le fichier
La deuxième option recherche le numéro de ligne de la première correspondance (vous pouvez également changer cela en changeant la "tête" intérieure) et utilise la tête sur ce numéro
La dernière option remplace toutes les nouvelles lignes par la correspondance et remplace ensuite deux correspondances adjacentes par une nouvelle ligne. La sortie de ceci est une ligne pour chaque bloc de texte entre deux correspondances. Après cela, il utilise 'head' pour choisir la première ligne (mwaning le bloc de texte jusqu'à la première correspondance) et ensuite retraduit chaque correspondance en une nouvelle ligne. cette option ne fonctionne que si le fichier est au format suivant
pattern
texttexttext
texttexttext texttexttext
texttexttexttexttexttexttexttexttext
pattern
texttexttext
pattern
texttexttext
texttexttexttexttexttexttexttexttext
et ainsi de suite