Solo como una nota, la versión de pegar que probé requiere un argumento "-" al final para decirle que lea desde STDIN. Por ejemplo, ls -1 | paste -s -d ":" - no estoy seguro si eso es universal con todas las versiones de pegar
Andy White
44
este es mejor porque permite delimitador vacío :)
Yura Purbeev
2
Note pasteobtiene -(entrada estándar) por defecto, al menos en mi paste (GNU coreutils) 8.22.
Fedorqui 'así que deja de dañar'
1
acabo de votarlo, esto es y ahora tiene los mismos votos que la respuesta seleccionada. ESTA ES LA RESPUESTA. no se arrastra delimeter
thebugfinder
1
El delimitador vacío se puede especificar usando "\0", ¡así que paste -sd "\0" -funcionó para mí!
Brad Parks
378
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"
Esto no se ocupará de los archivos con espacios en blanco en el nombre. Pruebe este: dir = / tmp / testdir; rm -rf $ dir && mkdir $ dir && cd / $ dir && toque "this is a file" this_is_another_file && ls -1 && files = ($ (ls -1)) && list = $ {files [@] /% / ,} && list = $ {list% *,} && echo $ list
dimir
1
@dimir: Muchas de las respuestas a esta pregunta sufren de este problema. He editado mi respuesta para permitir nombres de archivo con pestañas o espacios, pero no nuevas líneas.
Pausado hasta nuevo aviso.
Su versión bash también sufre expansiones de nombre de ruta. Para construir una matriz de líneas, por favor, considere el uso de mapfile(Bash ≥4) como: mapfile -t files < <(ls -1). No es necesario jugar con ellos IFS. Y también es más corto.
gniourf_gniourf
Y cuando se tiene la matriz, se puede utilizar IFSpara 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.
gniourf_gniourf
1
@gniourf_gniourf: He incluido sus sugerencias en mi respuesta. Gracias.
Pausado hasta nuevo aviso.
24
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.
¿Tienes más información sobre cómo setfunciona? A mí me parece un poco vudú. una mirada superficial man settampoco me proporcionó mucha información.
Ehtesh Choudhury
3
Si da setun montón de argumentos pero no tiene opciones, establece los parámetros posicionales ($ 1, $ 2, ...). --está allí para proteger seten 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[*]}" )
Glenn Jackman
Esto es excelente ya que no requiere la ejecución de ningún programa adicional y funciona con nombres de archivos que contienen espacios o incluso líneas nuevas.
Eric
1
@EhteshChoudhury Como type setle dirá, set is a shell builtin. Por lo tanto, man setno ayudará, pero help setlo hará. Respuesta: "- Asigne cualquier argumento restante a los parámetros posicionales".
Stéphane Gourichon
Después de a 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.
Isaac
13
No se recomienda analizar lsen general , por lo que una mejor forma alternativa es usar , por ejemplo:find
El OP quería cualquier delimitador, por lo que aún necesitaría un tr para convertir las comas. También agrega un espacio después de las comas, es decir, archivo1, archivo2, archivo3
robe el
así que usando ls -my trpara eliminar el espacio después de la coma que haríasls -m | tr -d ' '
Andy
2
ese uso de tr eliminará espacios dentro de los nombres de archivo. mejor usosed 's/, /,/g
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 gheadque tiene un conteo de bytes negativo, o mejor, hacer un alias:
Nota: los recuentos de bytes negativos solo son compatibles con ciertas versiones de head, por lo que esto no funcionará, por ejemplo, en macos.
Peter
Gracias por señalar eso. He agregado una solución para MacOS.
Aleksander Stelmaczonek
4
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 1100000| sed ':a; N; $!ba; s/\n/,/g'| head -c 80# linear, in less than 0.1s
seq 1100000| sed ':a; /$/N; s/\n/,/; ta'| head -c 80# quadratic, hung
-despecifica 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.
Thor
3
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
ls -1 | paste -s -d ":" -
no estoy seguro si eso es universal con todas las versiones de pegarpaste
obtiene-
(entrada estándar) por defecto, al menos en mipaste (GNU coreutils) 8.22
."\0"
, ¡así quepaste -sd "\0" -
funcionó para mí!¡Ah, el poder y la simplicidad!
Cambie la coma " , " a lo que quiera. Tenga en cuenta que esto incluye una "coma final"
fuente
\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
aftertr
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 -m
incluye nuevas líneas en el carácter de ancho de pantalla (80 por ejemplo).Principalmente Bash (solo
ls
es externo):Usando
readarray
(akamapfile
) en Bash 4:Gracias a gniourf_gniourf por las sugerencias.
fuente
mapfile
(Bash ≥4) como:mapfile -t files < <(ls -1)
. No es necesario jugar con ellosIFS
. 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
ORS es el "separador de registro de salida" por lo que ahora sus líneas se unirán con una coma.
fuente
" 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 shellPara capturar la salida,
fuente
set
funciona? A mí me parece un poco vudú. una mirada superficialman 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 protegerset
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 enhelp 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á, perohelp 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
O usando
find
ypaste
: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 .
fuente
No reinventes la rueda.
Hace exactamente eso.
fuente
ls -m
ytr
para eliminar el espacio después de la coma que haríasls -m | tr -d ' '
sed 's/, /,/g
solo golpe
fuente
|
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:
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 ''
fuente
Para evitar una posible confusión de nueva línea para tr, podríamos agregar el indicador -b a ls:
fuente
Parece que las respuestas ya existen.
Si desea
a, b, c
formatear, usels -m
( la respuesta de Tulains Córdova )O si desea
a b c
formatear, usels | xargs
(versión simplificada de la respuesta de Chris J )O si desea cualquier otro delimitador como
|
, usels | paste -sd'|'
(aplicación de la respuesta de Artem )fuente
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):
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
: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".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:fuente
El camino sed,
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,
fuente
Si su versión de xargs admite el indicador -d, entonces esto debería funcionar
-d es la bandera delimitador
Si no tiene -d, puede intentar lo siguiente
El primer xargs le permite especificar su delimitador, que es una coma en este ejemplo.
fuente
-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.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) exts/\n/\\n/;
- reemplaza todos los EOL con\n
ta;
- goto label a si la coincidencia es exitosaTomado de mi blog .
fuente
Puedes usar:
fuente
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:El oscuro
-0777
hace que Perl lea toda la entrada antes de ejecutar el programa.alternativa de sed que no deja un delimitador final
fuente
ls
tiene la opción-m
de delimitar la salida con", "
una coma y un espacio.canalizar este resultado para
tr
eliminar el espacio o la coma le permitirá canalizar el resultado nuevamentetr
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.fuente
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 declaración if. Puede ser un carácter especial o cualquier delimitador.
fuente
Versión Quick Perl con manejo de barra final:
Para explicar:
fuente