Risposte:
Simile alla prima opzione ma omette il delimitatore finale
ls -1 | paste -sd "," -
paste
ottiene -
(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"
\n
al suo interno, questo sostituirà anche quello.
ls -1 | tr "\\n" "," | sed 's/\(.*\),/\1/'
sed
potresti essere un po 'più efficiente con il carattere di fine marcatore:ls -1 | tr "\\n" "," | sed 's/,$//'; echo ''
sed
after tr
sembra 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 ls
esterno):
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.
IFS
per 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 IFS
e 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 "$*")
set
funziona? A me sembra un po 'voodoo. Uno sguardo superficiale man set
non mi ha fornito molte informazioni.
set
un sacco di argomenti ma nessuna opzione, imposta i parametri posizionali ($ 1, $ 2, ...). --
è lì per proteggere set
nel 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 set
vi dirà, set is a shell builtin
. Quindi, man set
non aiuterà, ma help set
lo 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 ls
in generale non è consigliata , quindi un modo migliore alternativo è quello di utilizzare find
, ad esempio:
find . -type f -print0 | tr '\0' ','
O usando find
e 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 -m
e tr
per rimuovere lo spazio dopo la virgola che farestils -m | tr -d ' '
sed 's/, /,/g
bash
mystring=$(printf "%s|" *)
echo ${mystring%|}
|
trita il finale , @camh.
bash
coreutils giusti e gnuprintf
printf -v
funzionerà 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, c
formato, usa ls -m
( la risposta di Tulains Córdova )
O se vuoi il a b c
formato, 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 ghead
un 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.
-d
specifica 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 join
funzione integrata che non lascia un delimitatore finale:
ls | perl -F'\n' -0777 -anE 'say join ",", @F'
L'oscuro -0777
fa 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'
ls
ha l'opzione -m
per delimitare l'output con ", "
una virgola e uno spazio.
ls -m | tr -d ' ' | tr ',' ';'
reindirizzare questo risultato per tr
rimuovere lo spazio o la virgola consentirà di reindirizzare il risultato tr
per 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