J'ai un fichier appelé file.txt
. Comment imprimer la première ligne uniquement à l'aide de la commande grep
?
Bien que ce soit une application non conventionnelle de grep, vous pouvez le faire en utilisant
grep -m1 "" file.txt
Cela fonctionne parce que l'expression vide correspond à tout, tandis que -m1
provoque la sortie de grep après la première correspondance
-m NUM, --max-count=NUM
Stop reading a file after NUM matching lines.
Ce n'est pas quelque chose que grep
fait. Le nom "grep" lui-même est un acronyme pour "globalement rechercher une expression régulière et imprimer", qui est ce que la commande ed
g/re/p
le fait (pour une expression régulière donnée re
).
ed
est un éditeur de ligne interactif de 1969, mais il est probablement installé sur votre système aujourd'hui. Nous avons obtenu grep
de ed
, et il 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 place sed
:
$ sed -n '1p' file.txt
Le 1p
chaî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 1p
ferait (sans surprise) la même chose dans l'éditeur ed
d'ailleurs.
Le -n
supprime 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 indiqué (généralisation) que head -n N
est un peu comme sed 'Nq'
, c'est-à-dire "imprimer chaque ligne, mais quitter à la ligne N
". La raison pour laquelle head
a été incluse dans la norme était due à la symétrie avec tail
(et à la rétrocompatibilité avec les implémentations Unix existantes).
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.txt
fonctionnerait à sa place.
Si vous ne souhaitez imprimer la première ligne que si elle correspond à un motif, dirigez la tête vers grep
head -n 1 * | grep [pattern]
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 retirer 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 juste parce que vous pouvez faire quelque chose en (grep ou bash ou ... etc), ne signifie pas que vous devriez - il y a probablement un meilleur outil pour le travail. sed (sed 1q
ou sed -n 1p
) et tête (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 1
ou sed -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 improbable qu'un système qui possède grep
ne possède pas également head
, tail
et sed
.