Je voudrais joindre le résultat de ls -1
en une seule ligne et le délimiter avec tout ce que je veux.
Existe-t-il des commandes Linux standard que je peux utiliser pour y parvenir?
Similaire à la toute première option, mais omet le délimiteur de fin
ls -1 | paste -sd "," -
ls -1 | paste -s -d ":" -
je ne sais pas si c'est universel avec toutes les versions de pâtepaste
obtient-
(entrée standard) par défaut, au moins sur monpaste (GNU coreutils) 8.22
."\0"
, donc apaste -sd "\0" -
fonctionné pour moi!Ah, la puissance et la simplicité!
Changez la virgule " , " en ce que vous voulez. Notez que cela inclut une "virgule de fin"
la source
\n
, cela le remplacera également.ls -1 | tr "\\n" "," | sed 's/\(.*\),/\1/'
sed
pourriez être un peu plus efficace avec le caractère marqueur de fin:ls -1 | tr "\\n" "," | sed 's/,$//'; echo ''
sed
aprèstr
semble juste pour supprimer le dernier symbole semble déraisonnable. Je pars avecls -1 | tr '\n' ',' | head -c -1
Cela remplace la dernière virgule par une nouvelle ligne:
ls -m
inclut des sauts de ligne au niveau de la largeur de l'écran (80e par exemple).Surtout Bash (uniquement
ls
externe):Utiliser
readarray
(akamapfile
) dans Bash 4:Merci à gniourf_gniourf pour les suggestions.
la source
mapfile
(Bash ≥4) comme:mapfile -t files < <(ls -1)
. Pas besoin de jouer avecIFS
. Et c'est plus court aussi.IFS
pour rejoindre les champs:saveIFS=$IFS; IFS=,; list=${files[*]}; IFS=$saveIFS
. Ou utilisez une autre méthode si vous voulez un séparateur avec plus d'un caractère.Je pense que celui-ci est génial
ORS est le "séparateur d'enregistrements de sortie" donc maintenant vos lignes seront jointes par une virgule.
la source
" OR "
)La combinaison de la configuration
IFS
et de l'utilisation de"$*"
peut faire ce que vous voulez. J'utilise un sous-shell donc je n'interfère pas avec $ IFS de ce shellPour capturer la sortie,
la source
set
fonctionnement? Ça me ressemble un peu au vaudou. un regard superficiel à traversman set
ne m'a pas rapporté beaucoup d'informations non plus.set
un tas d'arguments mais pas d'options, il définit les paramètres de position ($ 1, $ 2, ...).--
est là pour protégerset
au cas où le premier argument (ou nom de fichier dans ce cas) arriverait à commencer par un tiret. Voir la description de l'--
option danshelp set
. Je trouve que les paramètres positionnels sont un moyen pratique de gérer une liste de choses. J'aurais également pu implémenter cela avec un tableau:output=$( files=(*); IFS=,; echo "${files[*]}" )
type set
vous le dira,set is a shell builtin
. Donc, çaman set
n'aidera pas, maishelp set
ça ira. Réponse: "- Attribuez tous les arguments restants aux paramètres de position."set -- *
. L' expansion Retarder d'*
un niveau vous pouvez obtenir la sortie correcte sans qu'il soit nécessaire d'une coquille sous:IFS=',' eval echo '"$*"'
. Bien sûr, cela changera les paramètres de position.L'analyse
ls
en général n'est pas conseillée , donc une meilleure alternative est d'utiliserfind
, par exemple:Ou en utilisant
find
etpaste
:Pour joindre généralement plusieurs lignes (non liées au système de fichiers), vérifiez: «Join» concis et portable sur la ligne de commande Unix .
la source
Ne réinventez pas la roue.
C'est exactement cela.
la source
ls -m
ettr
pour supprimer l'espace après la virgule, vous feriezls -m | tr -d ' '
sed 's/, /,/g
bash juste
la source
|
, @camh.bash
et gnu coreutilsprintf
printf -v
ne fonctionnera qu'en bash, tandis que la réponse présentée fonctionne sur de nombreux types de shell.|
, à condition que les deux lignes sont utilisées:printf -v mystring "%s|" * ; echo ${mystring%|}
.Cette commande est destinée aux fans de PERL:
Ici 40 est le code ascii octal pour l'espace.
-p traitera ligne par ligne et imprimera
-l se chargera de remplacer le \ n de fin par le caractère ascii que nous fournissons.
-e est d'informer PERL que nous faisons l'exécution en ligne de commande.
0 signifie qu'il n'y a en fait aucune commande à exécuter.
perl -e0 est identique à perl -e ''
la source
Pour éviter une confusion potentielle de nouvelle ligne pour tr, nous pourrions ajouter le drapeau -b à ls:
la source
Il semble que les réponses existent déjà.
Si vous voulez un
a, b, c
format, utilisezls -m
( réponse de Tulains Córdova )Ou si vous voulez un
a b c
format, utilisezls | xargs
(version simplifiée de la réponse de Chris J )Ou si vous voulez un autre délimiteur comme
|
, utilisezls | paste -sd'|'
(application de la réponse d' Artem )la source
La voie sed,
Remarque :
Ceci est de complexité linéaire, ne se substituant qu'une seule fois après que toutes les lignes ont été ajoutées dans le Pattern Space de sed.
@ La réponse d'AnandRajaseka , et quelques autres réponses similaires, comme ici , sont O (n²), car sed doit faire un substitut chaque fois qu'une nouvelle ligne est ajoutée dans le Pattern Space.
Comparer,
la source
En plus de la réponse de majkinetor, voici la façon de supprimer le délimiteur de fin (car je ne peux pas encore commenter sous sa réponse):
Supprimez simplement autant d'octets de fin que votre délimiteur compte.
J'aime cette approche car je peux utiliser des délimiteurs multi-caractères et d'autres avantages de
awk
:ÉDITER
Comme Peter l'a remarqué, le nombre d'octets négatifs n'est pas pris en charge dans la version native de head de MacOS. Cependant, cela peut être facilement résolu.
Tout d'abord, installez
coreutils
. "Les utilitaires GNU Core sont les utilitaires de base de manipulation de fichiers, de shell et de texte du système d'exploitation GNU."Les commandes également fournies par MacOS sont installées avec le préfixe "g". Par exemple
gls
.Une fois que vous avez fait cela, vous pouvez utiliser
ghead
un nombre d'octets négatif, ou mieux, créer un alias:la source
Si votre version de xargs prend en charge l'indicateur -d, cela devrait fonctionner
-d est le drapeau de délimitation
Si vous n'avez pas -d, vous pouvez essayer ce qui suit
Le premier xargs vous permet de spécifier votre délimiteur qui est une virgule dans cet exemple.
la source
-d
spécifie le délimiteur d'entrée avec des xargs GNU, donc ne fonctionnera pas. Le deuxième exemple présente le même problème que d'autres solutions ici d'un délimiteur errant à la fin.Explication:
-e
- indique une commande à exécuter:a
- est une étiquette/$/N
- définit la portée de la correspondance pour la ligne actuelle et la ligne (N) exts/\n/\\n/;
- remplace tous les EOL par\n
ta;
- goto étiquette a si la correspondance est réussieTiré de mon blog .
la source
Vous pouvez utiliser:
la source
ls
produit une sortie de colonne lorsqu'il est connecté à un tuyau, il-1
est donc redondant.Voici une autre réponse Perl utilisant la
join
fonction intégrée qui ne laisse pas de délimiteur de fin:L'obscur
-0777
fait perl lire toutes les entrées avant d'exécuter le programme.alternative sed qui ne laisse pas de délimiteur de fin
la source
ls
a la possibilité-m
de délimiter la sortie avec", "
une virgule et un espace.canaliser ce résultat pour
tr
supprimer l'espace ou la virgule vous permettra de rediriger le résultattr
pour remplacer le délimiteur.dans mon exemple, je remplace le délimiteur
,
par le délimiteur;
remplacez-le
;
par le délimiteur que vous préférez, car tr ne représente que le premier caractère des chaînes que vous passez en arguments.la source
Vous pouvez utiliser chomp pour fusionner plusieurs lignes en une seule ligne:
perl -e 'while (<>) {if (/ \ $ /) {chomp; } print;} 'bad0> test
mettre la condition de saut de ligne dans l'instruction if. Il peut s'agir d'un caractère spécial ou d'un délimiteur.
la source
Version Perl rapide avec gestion des barres obliques de fin:
Expliquer:
la source