Respuestas:
Similar a la primera opción pero omite el delimitador final
ls -1 | paste -sd "," -
paste
obtiene -
(entrada estándar) por defecto, al menos en mi paste (GNU coreutils) 8.22
.
"\0"
, ¡así que paste -sd "\0" -
funcionó para mí!
EDITAR : Simplemente " ls -m " Si desea que su delimitador sea una coma
¡Ah, el poder y la simplicidad!
ls -1 | tr '\n' ','
Cambie la coma " , " a lo que quiera. Tenga en cuenta que esto incluye una "coma final"
\n
, también lo reemplazará.
ls -1 | tr "\\n" "," | sed 's/\(.*\),/\1/'
sed
podría ser un poco más eficiente con el carácter de marcador final:ls -1 | tr "\\n" "," | sed 's/,$//'; echo ''
sed
after tr
parece simplemente eliminar el último símbolo no parece razonable. Voy conls -1 | tr '\n' ',' | head -c -1
Esto reemplaza la última coma con una nueva línea:
ls -1 | tr '\n' ',' | sed 's/,$/\n/'
ls -m
incluye nuevas líneas en el carácter de ancho de pantalla (80 por ejemplo).
Principalmente Bash (solo ls
es externo):
saveIFS=$IFS; IFS=$'\n'
files=($(ls -1))
IFS=,
list=${files[*]}
IFS=$saveIFS
Usando readarray
(aka mapfile
) en Bash 4:
readarray -t files < <(ls -1)
saveIFS=$IFS
IFS=,
list=${files[*]}
IFS=$saveIFS
Gracias a gniourf_gniourf por las sugerencias.
mapfile
(Bash ≥4) como: mapfile -t files < <(ls -1)
. No es necesario jugar con ellos IFS
. Y también es más corto.
IFS
para unirse a los campos: saveIFS=$IFS; IFS=,; list=${files[*]}; IFS=$saveIFS
. O use otro método si desea un separador con más de un carácter.
Creo que este es genial
ls -1 | awk 'ORS=","'
ORS es el "separador de registro de salida" por lo que ahora sus líneas se unirán con una coma.
" OR "
)
La combinación de configuración IFS
y uso de "$*"
puede hacer lo que quieras. Estoy usando un subshell para no interferir con el $ IFS de este shell
(set -- *; IFS=,; echo "$*")
Para capturar la salida,
output=$(set -- *; IFS=,; echo "$*")
set
funciona? A mí me parece un poco vudú. una mirada superficial man set
tampoco me proporcionó mucha información.
set
un montón de argumentos pero no tiene opciones, establece los parámetros posicionales ($ 1, $ 2, ...). --
está allí para proteger set
en caso de que el primer argumento (o nombre de archivo en este caso) comience con un guión. Vea la descripción de la --
opción en help set
. Considero que los parámetros posicionales son una forma conveniente de manejar una lista de cosas. También podría haber implementado esto con una matriz:output=$( files=(*); IFS=,; echo "${files[*]}" )
type set
le dirá, set is a shell builtin
. Por lo tanto, man set
no ayudará, pero help set
lo hará. Respuesta: "- Asigne cualquier argumento restante a los parámetros posicionales".
set -- *
. El retraso de la expansión de *
un nivel que puede obtener la salida correcta sin la necesidad de una concha substitución: IFS=',' eval echo '"$*"'
. Por supuesto, eso cambiará los parámetros posicionales.
No se recomienda analizar ls
en general , por lo que una mejor forma alternativa es usar , por ejemplo:find
find . -type f -print0 | tr '\0' ','
O usando find
y paste
:
find . -type f | paste -d, -s
Para unir en general varias líneas (no relacionadas con el sistema de archivos), marque: "unión" concisa y portátil en la línea de comandos de Unix .
No reinventes la rueda.
ls -m
Hace exactamente eso.
ls -m
y tr
para eliminar el espacio después de la coma que haríasls -m | tr -d ' '
sed 's/, /,/g
solo golpe
mystring=$(printf "%s|" *)
echo ${mystring%|}
|
muerde el rastro, @camh.
bash
y gnu coreutilsprintf
printf -v
solo funcionará en bash, mientras que la respuesta presentada funciona en muchos tipos de shell.
|
, siempre que se utilicen ambas líneas: printf -v mystring "%s|" * ; echo ${mystring%|}
.
Este comando es para los fanáticos de PERL:
ls -1 | perl -l40pe0
Aquí 40 es el código ascii octal para el espacio.
-p procesará línea por línea e imprimirá
-l se encargará de reemplazar el \ n final con el carácter ascii que proporcionamos.
-e informa a PERL que estamos realizando la ejecución de la línea de comandos.
0 significa que en realidad no hay ningún comando para ejecutar.
perl -e0 es lo mismo que perl -e ''
Parece que las respuestas ya existen.
Si desea
a, b, c
formatear, use ls -m
( la respuesta de Tulains Córdova )
O si desea a b c
formatear, use ls | xargs
(versión simplificada de la respuesta de Chris J )
O si desea cualquier otro delimitador como |
, use ls | paste -sd'|'
(aplicación de la respuesta de Artem )
Además de la respuesta de majkinetor, esta es la forma de eliminar el delimitador final (ya que todavía no puedo comentar debajo de su respuesta):
ls -1 | awk 'ORS=","' | head -c -1
Simplemente elimine tantos bytes finales como su delimitador cuenta.
Me gusta este enfoque porque puedo usar delimitadores de caracteres múltiples + otros beneficios de awk
:
ls -1 | awk 'ORS=", "' | head -c -2
EDITAR
Como Peter ha notado, el recuento de bytes negativo no es compatible con la versión nativa de cabeza de MacOS. Sin embargo, esto se puede solucionar fácilmente.
Primero, instale coreutils
. "Las GNU Core Utilities son las utilidades básicas de manipulación de archivos, shell y texto del sistema operativo GNU".
brew install coreutils
Los comandos también proporcionados por MacOS se instalan con el prefijo "g". Por ejemplo gls
.
Una vez que haya hecho esto, puede usar el ghead
que tiene un conteo de bytes negativo, o mejor, hacer un alias:
alias head="ghead"
El camino 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 :
Esto es lineal en complejidad, sustituyéndose solo una vez después de que todas las líneas se agreguen al espacio de patrón de sed.
La respuesta de @ AnandRajaseka , y algunas otras respuestas similares, como aquí , son O (n²), porque sed tiene que sustituir cada vez que se agrega una nueva línea al Espacio del Patrón.
Comparar,
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
Si su versión de xargs admite el indicador -d, entonces esto debería funcionar
ls | xargs -d, -L 1 echo
-d es la bandera delimitador
Si no tiene -d, puede intentar lo siguiente
ls | xargs -I {} echo {}, | xargs echo
El primer xargs le permite especificar su delimitador, que es una coma en este ejemplo.
-d
especifica el delimitador de entrada con GNU xargs, por lo que no funcionará. El segundo ejemplo exhibe el mismo problema que otras soluciones aquí de un delimitador parásito al final.
sed -e :a -e '/$/N; s/\n/\\n/; ta' [filename]
Explicación:
-e
- denota un comando que se ejecutará
:a
- es una etiqueta
/$/N
- define el alcance de la coincidencia para la línea actual y la (N) ext
s/\n/\\n/;
- reemplaza todos los EOL con \n
ta;
- goto label a si la coincidencia es exitosa
Tomado de mi blog .
Puedes usar:
ls -1 | perl -pe 's/\n$/some_delimiter/'
ls
produce una salida de columna cuando se conecta a una tubería, por lo que -1
es redundante.
Aquí hay otra respuesta perl usando la join
función incorporada que no deja un delimitador final:
ls | perl -F'\n' -0777 -anE 'say join ",", @F'
El oscuro -0777
hace que Perl lea toda la entrada antes de ejecutar el programa.
alternativa de sed que no deja un delimitador final
ls | sed '$!s/$/,/' | tr -d '\n'
ls
tiene la opción -m
de delimitar la salida con ", "
una coma y un espacio.
ls -m | tr -d ' ' | tr ',' ';'
canalizar este resultado para tr
eliminar el espacio o la coma le permitirá canalizar el resultado nuevamente tr
para reemplazar el delimitador.
en mi ejemplo, reemplazo el delimitador ,
con el delimitador;
reemplace ;
con cualquier delimitador de caracteres que prefiera, ya que tr solo representa el primer carácter en las cadenas que pasa como argumentos.
Versión Quick Perl con manejo de barra final:
ls -1 | perl -E 'say join ", ", map {chomp; $_} <>'
Para explicar:
ls -1 | paste -s -d ":" -
no estoy seguro si eso es universal con todas las versiones de pegar