varios renombrar para mover masivo directorio copiar comandos comando archivos archivo linux bash shell parsing merge

linux - renombrar - ¿Cómo unir varias líneas de nombres de archivos en uno con un delimitador personalizado?



renombrar directorio linux (19)

EDIT : Simplemente " ls -m " si desea que su delimitador sea una coma

¡Ah, el poder y la sencillez!

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

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

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?


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

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


Creo que este es impresionante

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.


Este comando es para los fans de PERL:

ls -1 | perl -l40pe0

Aquí 40 es el código octal de ascii para el espacio.

-p procesará línea por línea e imprimirá

-Me encargaré de reemplazar el / n con el carácter ascii que proporcionamos.

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

0 significa que en realidad no hay comando para ejecutar.

perl -e0 es igual que perl -e ''''


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).

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.


La combinación de la configuración de IFS y el uso de "$*" puede hacer lo que desee. Estoy usando un subshell para no interferir con los $ IFS de este shell.

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

Para capturar la salida,

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


La forma 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, sustituyendo solo una vez después de que todas las líneas se agreguen en el Espacio de Patrones de sed.

La answer @ AnandRajaseka, y algunas otras respuestas similares, como here , son O (n²), porque sed tiene que hacer un sustituto cada vez que se agrega una nueva línea en el Espacio de Patrones.

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


No reinventes la rueda.

ls -m

Hace exactamente eso.


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

ls -1b | tr ''/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 quieres formato abc , usa ls | xargs xargs (versión simplificada de la respuesta de Chris J )

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


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

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

O usando find y paste :

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

Para unir líneas múltiples en general (no relacionadas con el sistema de archivos), marque: Concisión y "unión" portátil en la línea de comandos de Unix .


Puede usar chomp para fusionar varias líneas en una sola línea:

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

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


Puedes usar:

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


Si la versión de xargs admite la marca -d, esto debería funcionar

ls | xargs -d, -L 1 echo

-d es la bandera delimitadora

Si no tiene -d, puede probar lo siguiente

ls | xargs -I {} echo {}, | xargs echo

El primer xargs le permite especificar su delimitador, que es una coma en este ejemplo.


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

ls -1 | paste -sd "," -


solo bash

mystring=$(printf "%s|" *) echo ${mystring%|}


ls produce una salida de columna cuando se conecta a una tubería, por lo que el -1 es redundante.

Aquí hay otra respuesta de Perl usando la función incorporada de join 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 sed que no deja un delimitador al final.

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


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

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

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

en mi ejemplo sustituyo el delimitador con el delimitador ;

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


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 alcance de la coincidencia para la línea actual y (N) ext.
s//n///n/; - reemplaza todo EOL con /n
ta; - Ir a etiquetar a si el partido es exitoso

Tomado de mi blog .