Comment imprimer la première ligne en utilisant la commande grep?


17

J'ai un dossier appelé file.txt. Comment imprimer la première ligne uniquement à l'aide de la grepcommande?


4
Ne head -1 file.txtfonctionnerait pas?
clk

@steeldriver vous devez en faire une réponse car c'est la façon de le faire avec grep, un outil étrangement sélectionné pour le travail.
MelBurslan

1
grepn'est pas le meilleur outil pour imprimer la première ligne d'un fichier. Si vous vouliez simplement dire que vous vouliez imprimer la première ligne correspondant à grep, ou si vous avez une utilisation spécifique pour grep, veuillez nous le faire savoir. Si nous avions plus de contexte, nous pourrions peut-être donner une réponse qui aiderait mieux vous et la communauté.
DKing

@MelBurslan Dans file.txt, j'ai trois lignes par exemple: Ceci est un nouveau fichier. Deuxième ligne: le nom du fichier est newFile Troisième ligne: je n'ai pas créé la nouvelle ligne. Donc, en utilisant la commande grep, comment puis-je imprimer la première ligne uniquement? Comment la commande m'aidera-t-elle à imprimer la première et la dernière ligne? Pouvez-vous me dire les commandes pour les deux questions?
Nithin Santhosh du

Si l'une des réponses existantes résout votre problème, veuillez envisager de l'accepter via la coche. Je vous remercie!
Jeff Schaller

Réponses:


38

Bien que ce soit une application non conventionnelle de grep, vous pouvez le faire en utilisant

grep -m1 "" file.txt

Cela fonctionne car l'expression vide correspond à n'importe quoi, tandis que -m1grep se ferme après la première correspondance

-m NUM, --max-count=NUM
       Stop reading a file after NUM matching lines.

+1 pour avoir montré que la banane enrobée de chocolat n'est pas aussi inutile ici que je le pensais.
Kamil Maciorowski

4
Cela peut fonctionner sur certains systèmes, mais ce n'est pas portable:grep: unknown option -- m
Kusalananda

1
Notez la différence entre «première ligne» et «première ligne appariée»
Charles

13

Ce n'est pas quelque chose grep. Le nom "grep" lui-même est un acronyme pour " rechercher globalement une expression régulière et imprimer", ce que fait la edcommande g/re/p(pour une expression régulière donnée re).

edest un éditeur de ligne interactif de 1969, mais il est probablement installé sur votre système aujourd'hui. Nous venons grepde ed, et cela peut être vu comme un raccourci ou un alias pour une fonctionnalité spécifique de ed, et sed, qui est "stream- ed", c'est-à-dire un éditeur de flux (non interactif).

Utilisons à la sedplace:

$ sed -n '1p' file.txt

La 1pchaîne est un minuscule sed"script" qui affiche ( p) la ligne correspondant à l'adresse donnée ( 1, la première ligne). La commande d'édition 1pferait (sans surprise) la même chose dans l' edéditeur d'ailleurs.

Le -nsupprime la sortie de tout ce qui n'est pas explicitement imprimé par le script, donc tout ce que nous obtenons est la première ligne du fichier file.txt.

Alternativement:

$ sed '1q' file.txt

Cela imprime toutes les lignes du fichier, mais quitte ( q) à la ligne 1 (après l'avoir imprimé). C'est exactement équivalent à head -n 1 file.txt.

Dans la norme POSIX, il est dit (généralisation) que head -n Nc'est à peu près la même chose sed 'Nq', c'est-à-dire "imprimer chaque ligne, mais quitter à la ligne N". La raison qui a headété incluse dans la norme était due à la symétrie avec tail(et la compatibilité descendante avec les implémentations Unix existantes).


C'est la réponse la plus éclairante, la première réponse est un hack bizarre. Je savais qu'il y avait quelque chose de bizarre, merci de me montrer l'histoire de grep et ed. Tout s'explique maintenant.
Tomas Zubiri

6

Sauf si la première ligne a une chaîne unique, vous ne pouvez pas le faire en utilisant uniquement grep. head -n 1 file.txtfonctionnerait à sa place.

Si vous ne souhaitez imprimer la première ligne que si elle correspond à un modèle, dirigez la tête vers grep

head -n 1 * | grep [pattern]


2

Pourtant, une autre utilisation non conventionnelle de Grep - une transformation schwartzienne qui passe par plusieurs girations pour numéroter les lignes, puis utilise grep pour rechercher le numéro de ligne, puis enlève le numéro de ligne:

function grep1() (
  nlines=$(wc -l < "$1")
  nlw=$(printf "%d" "$nlines" | wc -c)
  nl -d '\n' -ba -n ln -w "$nlw" -s ' ' "$1" | grep '^1 ' | sed 's/^1 *//'
)

function greplast() (
  nlines=$(wc -l < "$1")
  nlines=$((nlines + 0))
  nlw=$(printf "%d" "$nlines" | wc -c)
  nl -d '\n' -ba -n ln -w "$nlw" -s ' ' "$1" | grep "^$nlines " | sed "s/^$nlines *//"
)

Je mets cette réponse ici comme exemple de l'idée que ce n'est pas parce que vous pouvez faire quelque chose dans (grep ou bash ou ... etc) que vous devriez - il y a probablement un meilleur outil pour le travail. sed ( sed 1qou sed -n 1p) et head ( head -n 1) sont les outils les plus appropriés pour imprimer la première ligne d'un fichier. Pour imprimer la dernière ligne d'un fichier, vous avez tail -n 1oused -n '$p'. Non seulement ces outils sont une commande unique (au lieu de 3+ dans les fonctions ci-dessus), ils sont également beaucoup plus clairs pour les futurs lecteurs - peut-être vous-même! - des scripts dans lesquels ils se trouvent. Bien que je ne sois pas l'un des (actuellement 3) votants de votre question, il est probable que votre insistance sur un outil arbitraire pour le travail (sans aucune raison à l'appui) soit la raison de les downvotes. Il est extrêmement peu probable qu'un système qui a grepne pas aussi head, tailet sed.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.