¿Cómo unir múltiples líneas de nombres de archivos en uno con delimitador personalizado?

Me gustaría unir el resultado de ls -1 en una línea y delimitarlo con lo que quiera.

¿Hay algún comando estándar de Linux que pueda usar para lograr esto?

Similar a la primera opción pero omite el delimitador final

 ls -1 | paste -sd "," - 

EDITAR : Simplemente ” ls -m ” Si quieres que tu delimitador sea una coma

Ah, el poder y la simplicidad!

 ls -1 | tr '\n' ',' 

Cambia la coma ” , ” a lo que quieras. Tenga en cuenta que esto incluye una “coma final”

Esto reemplaza la última coma con una nueva línea:

 ls -1 | tr '\n' ',' | sed 's/,$/\n/' 

ls -m incluye líneas nuevas en el carácter de ancho de pantalla (80º por ejemplo).

Mayormente Bash (solo ls es externo):

 saveIFS=$IFS; IFS=$'\n' files=($(ls -1)) IFS=, list=${files[*]} IFS=$saveIFS 

Usando readarray (también mapfile como mapfile ) en Bash 4:

 readarray -t files < <(ls -1) saveIFS=$IFS IFS=, list=${files[*]} IFS=$saveIFS 

Gracias a gniourf_gniourf por las sugerencias.

Creo que este es asombroso

 ls -1 | awk 'ORS=" "' 

La combinación de configuración de IFS y el uso de "$*" puede hacer lo que desee. Estoy usando una subshell así que no interfiero con $ IFS de este shell

 (set -- *; IFS=,; echo "$*") 

Para capturar la salida,

 output=$(set -- *; IFS=,; echo "$*") 

No se recomienda analizar ls en general, por lo que una mejor alternativa es utilizar find , por ejemplo:

 find . -type f -print0 | tr '\0' ',' 

O mediante el uso de find y paste :

 find . -type f | paste -d, -s 

Para unir líneas múltiples (no relacionadas con el sistema de archivos), verifique: “unirse” conciso y portátil en la línea de comandos de Unix .

No reinventar la rueda.

 ls -m 

Hace exactamente eso.

solo bash

 mystring=$(printf "%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á

-Me ocuparé de reemplazar el \ nque arrastra \ n con el carácter ascii que proporcionamos.

-e es informar a PERL que estamos haciendo la ejecución de línea de comando.

0 significa que no hay ningún comando para ejecutar.

perl -e0 es lo mismo que perl -e ”

Para evitar la posible confusión de nueva línea para tr, podríamos agregar el distintivo -b a ls:

 ls -1b | tr '\n' ';' 
 sed -e :a -e '/$/N; s/\n/\\n/; ta' [filename] 

Explicación:

-e – denota un comando para ser ejecutado
:a – es una etiqueta
/$/N – define el scope de la coincidencia para la línea actual y (N) ext
s/\n/\\n/; – reemplaza todo EOL con \n
ta; – etiqueta ir a si la coincidencia es exitosa

Tomado de mi blog .

Puedes usar:

 ls -1 | perl -pe 's/\n$/some_delimiter/' 

Si su versión de xargs admite el indicador -d, esto debería funcionar

 ls | xargs -d, -L 1 echo 

-d es la bandera del delimitador

Si no tiene -d, entonces 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.

ls produce una salida de columna cuando está conectado a una tubería, por lo que -1 es redundante.

Aquí hay otra respuesta perl usando la función de join integrada 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 progtwig.

alternativa sed que no deja un delimitador final

 ls | sed '$!s/$/,/' | tr -d '\n' 

Parece que las respuestas ya existen.

Si quieres el formato a a, b, c , usa ls -m ( respuesta de Tulains Córdova )

O si quiere formato abc , use ls | xargs xargs (versión simplificada de la respuesta de Chris J )

O si quieres cualquier otro delimitador como | , use ls | paste -sd'|' ls | paste -sd'|' (aplicación de la respuesta de Artem )

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éndolo una sola vez después de que todas las líneas se anexen 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 de 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 

Agregando encima de la respuesta de majkinetor, aquí está la manera de eliminar el delimitador final (ya que no puedo comentar solo bajo su respuesta):

 ls -1 | awk 'ORS=","' | head -c -1 

Simplemente elimine tantos bytes finales como cuente su delimitador.

Me gusta este enfoque porque puedo usar delimitadores de múltiples caracteres + otros beneficios de awk :

 ls -1 | awk 'ORS=", "' | head -c -2 

Tiene la opción -m para delimitar la salida con ", " una coma y un espacio.

 ls -m | tr -d ' ' | tr ',' ';' 

conectar este resultado a tr para eliminar el espacio o la coma le permitirá conectar nuevamente el resultado a tr para reemplazar el delimitador.

en mi ejemplo, reemplazo el delimitador , con el delimitador ;

reemplazar ; con cualquier delimitador de caracteres que prefiera, ya que tr solo representa el primer carácter de las cadenas que pasa como argumentos.

Puede usar chomp para combinar líneas múltiples en una sola línea:

perl -e ‘while (<>) {if (/ \ $ /) {chomp; } print;} ‘bad0> prueba

poner condición de salto de línea en la sentencia if. Puede ser un carácter especial o cualquier delimitador.