Risposte:
Simile alla prima opzione ma omette il delimitatore finale
ls -1 | paste -sd "," -
pasteottiene -(input standard) come predefinito, almeno sul mio paste (GNU coreutils) 8.22.
"\0", quindi ha paste -sd "\0" -funzionato per me!
EDIT : semplicemente " ls -m " Se vuoi che il delimitatore sia una virgola
Ah, il potere e la semplicità!
ls -1 | tr '\n' ','
Cambia la virgola " , " come preferisci. Nota che questo include una "virgola finale"
\nal suo interno, questo sostituirà anche quello.
ls -1 | tr "\\n" "," | sed 's/\(.*\),/\1/'
sedpotresti essere un po 'più efficiente con il carattere di fine marcatore:ls -1 | tr "\\n" "," | sed 's/,$//'; echo ''
sedafter trsembra solo rimuovere l'ultimo simbolo sembra irragionevole. Vado conls -1 | tr '\n' ',' | head -c -1
Questo sostituisce l'ultima virgola con una nuova riga:
ls -1 | tr '\n' ',' | sed 's/,$/\n/'
ls -m include newline al carattere di larghezza dello schermo (80 ° per esempio).
Principalmente Bash (solo lsesterno):
saveIFS=$IFS; IFS=$'\n'
files=($(ls -1))
IFS=,
list=${files[*]}
IFS=$saveIFS
Usando readarray(aka mapfile) in Bash 4:
readarray -t files < <(ls -1)
saveIFS=$IFS
IFS=,
list=${files[*]}
IFS=$saveIFS
Grazie a gniourf_gniourf per i suggerimenti.
mapfile (Bash ≥4) come: mapfile -t files < <(ls -1). Non c'è bisogno di giocherellare IFS. Ed è anche più corto.
IFSper unire i campi: saveIFS=$IFS; IFS=,; list=${files[*]}; IFS=$saveIFS. Oppure usa un altro metodo se vuoi un separatore con più di un carattere.
Penso che questo sia fantastico
ls -1 | awk 'ORS=","'
ORS è il "separatore del record di output", quindi ora le tue linee verranno unite con una virgola.
" OR ")
La combinazione di impostazione IFSe uso di "$*"può fare quello che vuoi. Sto usando una subshell quindi non interferisco con $ IFS di questa shell
(set -- *; IFS=,; echo "$*")
Per catturare l'output,
output=$(set -- *; IFS=,; echo "$*")
setfunziona? A me sembra un po 'voodoo. Uno sguardo superficiale man setnon mi ha fornito molte informazioni.
setun sacco di argomenti ma nessuna opzione, imposta i parametri posizionali ($ 1, $ 2, ...). --è lì per proteggere setnel caso in cui il primo argomento (o nome file in questo caso) inizi con un trattino. Vedi la descrizione --dell'opzione in help set. Trovo i parametri posizionali un modo conveniente per gestire un elenco di cose. Avrei potuto anche implementarlo con un array:output=$( files=(*); IFS=,; echo "${files[*]}" )
type setvi dirà, set is a shell builtin. Quindi, man setnon aiuterà, ma help setlo farà. Risposta: "- Assegna tutti gli argomenti rimanenti ai parametri posizionali."
set -- *. Ritardare l'espansione di *un livello che si può ottenere l'output corretto, senza la necessità di una conchiglia sub: IFS=',' eval echo '"$*"'. Naturalmente ciò cambierà i parametri posizionali.
L'analisi lsin generale non è consigliata , quindi un modo migliore alternativo è quello di utilizzare find, ad esempio:
find . -type f -print0 | tr '\0' ','
O usando finde paste:
find . -type f | paste -d, -s
Per l'unione generale di più righe (non correlate al file system), selezionare: "join" conciso e portatile sulla riga di comando Unix .
Non reinventare la ruota.
ls -m
Lo fa esattamente.
ls -me trper rimuovere lo spazio dopo la virgola che farestils -m | tr -d ' '
sed 's/, /,/g
bash
mystring=$(printf "%s|" *)
echo ${mystring%|}
|trita il finale , @camh.
bashcoreutils giusti e gnuprintf
printf -vfunzionerà solo in bash, mentre la risposta presentata funziona su molti tipi di shell.
|, a condizione che entrambe le linee vengono utilizzati: printf -v mystring "%s|" * ; echo ${mystring%|}.
Questo comando è per i fan di PERL:
ls -1 | perl -l40pe0
Qui 40 è il codice ascii ottale per lo spazio.
-p elaborerà riga per riga e stamperà
-l si occuperà di sostituire il finale \ n con il carattere ascii che forniamo.
-e deve informare PERL che stiamo eseguendo la riga di comando.
0 significa che in realtà non esiste alcun comando da eseguire.
perl -e0 è uguale a perl -e ''
Sembra che le risposte esistano già.
Se vuoi il
a, b, cformato, usa ls -m( la risposta di Tulains Córdova )
O se vuoi il a b cformato, usa ls | xargs(versione semplificata della risposta di Chris J )
O se vuoi qualsiasi altro delimitatore come |, usa ls | paste -sd'|'(applicazione della risposta di Artem )
Aggiungendo in cima alla risposta di majkinetor, ecco il modo di rimuovere il delimitatore finale (dal momento che non posso ancora commentare sotto la sua risposta):
ls -1 | awk 'ORS=","' | head -c -1
Basta rimuovere tutti i byte finali quanti conta il delimitatore.
Mi piace questo approccio perché posso usare delimitatori multi carattere + altri vantaggi di awk:
ls -1 | awk 'ORS=", "' | head -c -2
MODIFICARE
Come ha notato Peter, il conteggio di byte negativi non è supportato nella versione nativa di MacOS di head. Questo tuttavia può essere facilmente risolto.
Innanzitutto, installa coreutils. "Le GNU Core Utilities sono le utilità di base per la manipolazione di file, shell e testo del sistema operativo GNU."
brew install coreutils
I comandi forniti anche da MacOS sono installati con il prefisso "g". Per esempiogls .
Una volta fatto ciò, puoi usare gheadun numero di byte negativo, o meglio, creare un alias:
alias head="ghead"
Il modo 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
Nota :
Questo è lineare nella complessità, sostituendo una sola volta dopo che tutte le linee sono state aggiunte nello spazio modello di sed.
La risposta di AnandRajaseka e alcune altre risposte simili, come qui , sono O (n²), perché sed deve sostituire ogni volta che una nuova riga viene aggiunta nello spazio modello.
Per confrontare,
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
Se la tua versione di xargs supporta il flag -d, questo dovrebbe funzionare
ls | xargs -d, -L 1 echo
-d è la bandiera del delimitatore
Se non hai -d, puoi provare quanto segue
ls | xargs -I {} echo {}, | xargs echo
I primi xargs ti consentono di specificare il delimitatore che è una virgola in questo esempio.
-dspecifica il delimitatore di input con xarg GNU, quindi non funzionerà. Il secondo esempio mostra lo stesso problema di altre soluzioni qui di un delimitatore vagante alla fine.
sed -e :a -e '/$/N; s/\n/\\n/; ta' [filename]
Spiegazione:
-e- indica un comando da eseguire
:a- è un'etichetta
/$/N- definisce l'ambito della corrispondenza per la linea corrente e (N) ext
s/\n/\\n/;- sostituisce tutta l'EOL con\n
ta; - vai all'etichetta a se la corrispondenza ha esito positivo
Tratto dal mio blog .
Puoi usare:
ls -1 | perl -pe 's/\n$/some_delimiter/'
ls produce un output di colonna quando è collegato a una pipe, quindi il file -1 è ridondante.
Ecco un'altra risposta perl che utilizza la joinfunzione integrata che non lascia un delimitatore finale:
ls | perl -F'\n' -0777 -anE 'say join ",", @F'
L'oscuro -0777fa in modo che perl legga tutti gli input prima di eseguire il programma.
alternativa alternativa che non lascia un delimitatore finale
ls | sed '$!s/$/,/' | tr -d '\n'
lsha l'opzione -mper delimitare l'output con ", "una virgola e uno spazio.
ls -m | tr -d ' ' | tr ',' ';'
reindirizzare questo risultato per trrimuovere lo spazio o la virgola consentirà di reindirizzare il risultato trper sostituire il delimitatore.
nel mio esempio sostituisco il delimitatore ,con il delimitatore;
sostituisci ;con qualsiasi delimitatore di carattere che preferisci poiché tr considera solo il primo carattere nelle stringhe che passi come argomenti.
Versione Quick Perl con gestione della barra finale:
ls -1 | perl -E 'say join ", ", map {chomp; $_} <>'
Spiegare:
ls -1 | paste -s -d ":" -non sono sicuro che sia universale con tutte le versioni di pasta