J'aimerais joindre le résultat de ls -1
en une 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?
Semblable à la toute première option mais en omettant le délimiteur final
ls -1 | paste -sd "," -
EDIT: Simplement "ls -m" Si vous voulez que votre délimiteur soit une virgule
Ah, le pouvoir et la simplicité!
ls -1 | tr '\n' ','
Changez la virgule "," en ce que vous voulez. Notez que cela inclut une "virgule de fin"
Ceci remplace la dernière virgule par une nouvelle ligne:
ls -1 | tr '\n' ',' | sed 's/,$/\n/'
ls -m
inclut les nouvelles lignes au caractère de largeur d'écran (80e par exemple).
Principalement Bash (uniquement ls
est externe):
saveIFS=$IFS; IFS=$'\n'
files=($(ls -1))
IFS=,
list=${files[*]}
IFS=$saveIFS
Utilisation de readarray
(alias mapfile
) dans Bash 4:
readarray -t files < <(ls -1)
saveIFS=$IFS
IFS=,
list=${files[*]}
IFS=$saveIFS
Merci à gniourf_gniourf pour les suggestions.
Je pense que celui-ci est génial
ls -1 | awk 'ORS=","'
ORS est le "séparateur d'enregistrement de sortie". Vos lignes seront donc jointes par une virgule.
La combinaison du réglage IFS
et de l'utilisation de "$*"
peut faire ce que vous voulez. J'utilise un sous-shell afin que je n'interfère pas avec le $ IFS de ce shell
(set -- *; IFS=,; echo "$*")
Pour capturer la sortie,
output=$(set -- *; IFS=,; echo "$*")
Analyser ls
en général n'est pas conseillé , la meilleure façon de procéder consiste donc à utiliser find
, par exemple:
find . -type f -print0 | tr '\0' ','
Ou en utilisant find
et paste
:
find . -type f | paste -d, -s
Pour joindre en général plusieurs lignes (sans lien avec le système de fichiers), vérifiez: "jointure" concise et portable sur la ligne de commande Unix .
Ne réinventez pas la roue.
ls -m
C'est exactement ça.
Cette commande est pour les fans de Perl:
ls -1 | Perl -l40pe0
Ici 40 est le code ascii octal pour l'espace.
-p traitera ligne par ligne et imprimera
-l prendra soin de remplacer le\n trailing par le caractère ascii que nous fournissons.
-e est d'informer Perl que nous sommes en train d'exécuter la ligne de commande.
0 signifie qu'il n'y a en réalité aucune commande à exécuter.
Perl -e0 est identique à Perl -e ''
juste bash
mystring=$(printf "%s|" *)
echo ${mystring%|}
Pour éviter une éventuelle confusion de nouvelle ligne pour tr, nous pourrions ajouter le drapeau -b à ls:
ls -1b | tr '\n' ';'
Il semble que les réponses existent déjà.
Si vous voulez le format a, b, c
, utilisez ls -m
( réponse de Tulains Córdova )
Ou si vous voulez le format a b c
, utilisez ls | xargs
(version simplifiée de réponse de Chris J )
Ou si vous voulez un autre délimiteur comme |
, utilisez ls | paste -sd'|'
(application de réponse d'Artem )
sed -e :a -e '/$/N; s/\n/\\n/; ta' [filename]
Explication:
-e
- indique une commande à exécuter:a
- est une étiquette/$/N
- définit l'étendue de la correspondance pour la ligne courante et la ligne (N) exts/\n/\\n/;
- remplace tous les EOL par \n
ta;
- mentionne a si la correspondance est réussie
Tiré de mon blog .
Si votre version de xargs prend en charge l'indicateur -d, cela devrait fonctionner
ls | xargs -d, -L 1 echo
-d est le drapeau délimiteur
Si vous n'avez pas -d, alors vous pouvez essayer ce qui suit
ls | xargs -I {} echo {}, | xargs echo
Le premier xargs vous permet de spécifier votre délimiteur qui est une virgule dans cet exemple.
La voie sed,
sed -e ':a; N; $!ba; s/\n/,/g'
# :a # label called 'a'
# N # append next line into Pattern Space (see info sed)
# $!ba # if it's the last line ($) do not (!) jump to (b) label :a (a) - break loop
# s/\n/,/g # any substitution you want
Remarque :
Cette complexité est linéaire et ne remplace qu'une seule fois après l'ajout de toutes les lignes dans l'espace des motifs de sed.
@ (AnandRajaseka) réponse , et quelques autres réponses similaires, telles que ici , sont O (n²), car sed doit se substituer à chaque fois qu'une nouvelle ligne est ajoutée au motif Espace.
Comparer,
seq 1 100000 | sed ':a; N; $!ba; s/\n/,/g' | head -c 80
# linear, in less than 0.1s
seq 1 100000 | sed ':a; /$/N; s/\n/,/; ta' | head -c 80
# quadratic, hung
Vous pouvez utiliser:
ls -1 | Perl -pe 's/\n$/some_delimiter/'
ls
produit une sortie de colonne lorsqu'il est connecté à un tuyau, ainsi le -1
est redondant.
Voici une autre réponse Perl utilisant la fonction intégrée join
qui ne laisse pas de délimiteur final:
ls | Perl -F'\n' -0777 -anE 'say join ",", @F'
L'obscur -0777
permet à Perl de lire toutes les entrées avant d'exécuter le programme.
alternative sed qui ne laisse pas de délimiteur final
ls | sed '$!s/$/,/' | tr -d '\n'
Ajoutant en plus de la réponse de majkinetor, voici la manière de supprimer le délimiteur final (car je ne peux pas encore commenter sous sa réponse):
ls -1 | awk 'ORS=","' | head -c -1
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 + d'autres avantages de awk
:
ls -1 | awk 'ORS=", "' | head -c -2
EDIT
Comme Peter l’a remarqué, le nombre d’octets négatifs n’est pas pris en charge dans la version MacOS native de head. Cela peut cependant être facilement corrigé.
Tout d'abord, instal coreutils
. "Les GNU Core Utilities sont les utilitaires de base de fichiers, de shell et de manipulation de texte du système d'exploitation GNU."
brew install coreutils
Les commandes également fournies par MacOS sont installées avec le préfixe "g". Par exemple, gls
.
Une fois que cela est fait, vous pouvez utiliser ghead
qui a un nombre d'octets négatif ou supérieur, créez un alias:
alias head="ghead"
ls
a l'option -m
pour délimiter la sortie avec ", "
une virgule et un espace.
ls -m | tr -d ' ' | tr ',' ';'
si ce résultat est acheminé à tr
pour supprimer l’espace ou la virgule, vous pourrez rediriger le résultat vers tr
pour remplacer le délimiteur.
dans mon exemple, je remplace le délimiteur ,
par le délimiteur ;
remplacez ;
par quoi que ce soit n séparateur de caractères vous préférez, car tr ne rend compte que du premier caractère des chaînes que vous transmettez en tant qu'arguments.
Vous pouvez utiliser chomp pour fusionner plusieurs lignes en une seule ligne:
Perl -e 'while (<>) {if (/\$ /) {chomp; } print;} 'bad0> test
mettez la condition de saut de ligne dans l'instruction if.Il peut s'agir d'un caractère spécial ou de tout délimiteur.
Version Quick Perl avec gestion des slash de fin:
ls -1 | Perl -E 'say join ", ", map {chomp; $_} <>'
Expliquer: