@mattdm L'utilisation lsne fonctionnera pas si l'un des noms de fichier contient un blanc.
helpermethod
2
Comment définissez-vous le mot ? Si le premier fichier existe Sunset on a beach.jpg, doit-il s'agir d' Sunsetun nom de fichier complet? Qu'en est- il Sea, sex and sun.ogg? Sea, Sea,ou le nom du fichier entier?
Stéphane Chazelas
@mattdm ls | head -1me donne des choses aléatoires comme a.patch p.pyce qui n'est pas le premier mot et même pas les fichiers dans l'ordre alphabétique.
phuclv
Réponses:
52
Vous pouvez le faire passer à travers awk et faire en sorte qu'il répète le premier mot
echo *| head -n1 | awk '{print $1;}'
ou vous coupez la chaîne et sélectionnez le premier mot:
echo *| head -n1 | cut -d " "-f1
ou vous le dirigez et laissez-le supprimer tout, sauf le premier mot
echo *| head -n1 | sed -e 's/\s.*$//'
Ajouté le | head -n1pour satisfaire les nitpickers. Si votre chaîne contient des nouvelles lignes | head -n1, sélectionnez la première ligne avant que les commandes importantes ne sélectionnent le premier mot de la chaîne qui lui est transmise.
Le renverrait le premier mot de chaque ligne, pas le premier mot.
Stéphane Chazelas
2
Je me demande combien de lignes echo *génèrent
Bananguin
Cela dépend du nombre de fichiers avec des caractères de nouvelle ligne dans leur nom ou en fonction de l'environnement ou de la manière dont bash a été compilé ou encore si un fichier appelé -eou -ee... apparaît dans la liste, combien de fois il \napparaît dans un nom de fichier. S'il y a un fichier appelé -n, il risque de ne pas renvoyer de ligne du tout ...
Stéphane Chazelas
Eh bien, nous parlons toujours de bash et 1. d'habitude bash ne transmettra pas une chaîne avec des nouvelles lignes comme une chaîne avec de nouvelles lignes 2. il est très difficile et inhabituel (impossible?) D'avoir une nouvelle ligne dans un nom de fichier 3. a \ n in un nom de fichier apparaîtra sous la forme \ n 4. 3 est valable pour les noms de fichiers commençant par - 5. même lorsque vous appelez avec -n ou -e, echo ouvrira stdout et le fermera à la fin. Bien sûr, il retournera une ligne et au moins une chaîne, d'ailleurs 6. J'ai modifié mon conseil pour au moins prendre soin du problème multiligne
Bananguin
1
Tous les 5 points sont faux. Essayez dans un répertoire vide: touch '$a\nb' 'a\nb'; env BASHOPTS=xpg_echo bash -c 'echo * | wc -l'( xpg_echoest activé partout où il bashest requis d'être conforme à Unix). Et dans un autre répertoire vide: touch ./-n; bash -c 'echo * | wc -l'. Une ligne est une séquence de caractères terminée par un caractère de nouvelle ligne. Si echone produit pas de caractère de nouvelle ligne, aucune ligne n'est affichée. Le comportement des utilitaires de texte tels que cut, awkou sedn'est pas spécifié, si l'entrée comporte des caractères supplémentaires après le dernier caractère de nouvelle ligne et que le comportement varie selon les implémentations.
Stéphane Chazelas
18
En supposant un shell posixy ( /bin/shou /bin/bashpeut le faire)
all=$(echo *)
first=${all%%*}
La construction ${all%% *}est un exemple de suppression de sous - chaîne . Les %%moyens suppriment la correspondance la plus longue de *(un espace suivi de rien) de l'extrémité droite de la variable all. Vous pouvez en savoir plus sur la manipulation de chaîne ici .
Cette solution suppose que le séparateur est un espace. Si vous faites cela avec des noms de fichiers, tout espace avec des espaces le cassera.
Joli. Mais j'ai aimé l'autre version simple et plus non-hacky avec headetcut
Anwar le
4
IMO, head, cut & sed sont moins simples. Pourquoi créer un autre outil lorsque la substitution de paramètres intégrée effectue le travail efficacement. Cette réponse est le moyen le plus efficace et le plus portable de sélectionner le premier mot d'une liste de mots séparés par des espaces (ce qui correspond à tous les OP demandés).
Juan
7
En supposant que vous vouliez vraiment le premier nom de fichier et non le premier mot , voici une solution qui ne casse pas les blancs:
Le premier mot serait aussi facile:files=($(echo *))
Hauke Laging le
2
Il se briserait sur "-n", "-e", "-ne", "-Enenene" ..., et selon la façon dont il a bashété compilé ou l'environnement, éventuellement sur des barres obliques inverses.
Stéphane Chazelas
2
@HaukeLaging, vous devez désactiver le globbing. Comme text=$(echo *); set -f; files=($text):, sinon plus de jokers pourraient être étendus.
Stéphane Chazelas
3
etfiles=$(echo *); echo ${files%% *}
vdegenne
1
@ memnoch_proxy Cela va casser les noms de fichiers contenant des espaces, utilisez-le avec prudence.
Sachez que cela détruira tous les autres arguments de votre script, sauf s’il est exécuté dans une étendue auxiliaire. Il sera également étendu à *s'il n'y a aucun fichier dans le répertoire.
ls
ne fonctionnera pas si l'un des noms de fichier contient un blanc.Sunset on a beach.jpg
, doit-il s'agir d'Sunset
un nom de fichier complet? Qu'en est- ilSea, sex and sun.ogg
?Sea
,Sea,
ou le nom du fichier entier?ls | head -1
me donne des choses aléatoires commea.patch p.py
ce qui n'est pas le premier mot et même pas les fichiers dans l'ordre alphabétique.Réponses:
Vous pouvez le faire passer à travers awk et faire en sorte qu'il répète le premier mot
ou vous coupez la chaîne et sélectionnez le premier mot:
ou vous le dirigez et laissez-le supprimer tout, sauf le premier mot
Ajouté le
| head -n1
pour satisfaire les nitpickers. Si votre chaîne contient des nouvelles lignes| head -n1
, sélectionnez la première ligne avant que les commandes importantes ne sélectionnent le premier mot de la chaîne qui lui est transmise.la source
echo *
génèrent-e
ou-ee
... apparaît dans la liste, combien de fois il\n
apparaît dans un nom de fichier. S'il y a un fichier appelé-n
, il risque de ne pas renvoyer de ligne du tout ...touch '$a\nb' 'a\nb'; env BASHOPTS=xpg_echo bash -c 'echo * | wc -l'
(xpg_echo
est activé partout où ilbash
est requis d'être conforme à Unix). Et dans un autre répertoire vide:touch ./-n; bash -c 'echo * | wc -l'
. Une ligne est une séquence de caractères terminée par un caractère de nouvelle ligne. Siecho
ne produit pas de caractère de nouvelle ligne, aucune ligne n'est affichée. Le comportement des utilitaires de texte tels quecut
,awk
oused
n'est pas spécifié, si l'entrée comporte des caractères supplémentaires après le dernier caractère de nouvelle ligne et que le comportement varie selon les implémentations.En supposant un shell posixy (
/bin/sh
ou/bin/bash
peut le faire)La construction
${all%% *}
est un exemple de suppression de sous - chaîne . Les%%
moyens suppriment la correspondance la plus longue de*
(un espace suivi de rien) de l'extrémité droite de la variableall
. Vous pouvez en savoir plus sur la manipulation de chaîne ici .Cette solution suppose que le séparateur est un espace. Si vous faites cela avec des noms de fichiers, tout espace avec des espaces le cassera.
la source
head
etcut
En supposant que vous vouliez vraiment le premier nom de fichier et non le premier mot , voici une solution qui ne casse pas les blancs:
la source
files=($(echo *))
bash
été compilé ou l'environnement, éventuellement sur des barres obliques inverses.text=$(echo *); set -f; files=($text)
:, sinon plus de jokers pourraient être étendus.files=$(echo *); echo ${files%% *}
Vous pouvez utiliser les paramètres de position
la source
*
s'il n'y a aucun fichier dans le répertoire.shopt -s nullglob
traiterait queCochez l'une des alternatives suivantes:
Ensuite, vous pouvez l’imprimer via
echo $FILE
.Voir aussi:
grep
le seul premier mot de la sortie?la source
Cela marche:
Crédité sur https://unix.stackexchange.com/a/57879/3920
la source
Obtenir le premier nom de fichier complet:
la source