2010-10-07 16 views
123

Estoy usando el comando ls -a para obtener los nombres de los archivos en un directorio, pero el resultado está en una sola línea.¿Cómo puedo listar un nombre de archivo por línea de salida en Linux?

De esta manera: . .. .bash_history .ssh updator_error_log.txt

¿Existe una alternativa incorporado para obtener los nombres de archivos, cada uno en una nueva línea, así:

. 
.. 
.bash_history 
.ssh 
updator_error_log.txt 
+2

ls tiene como objetivo mostrar una lista para el consumo humano. Si está utilizando ls para cualquier otro propósito (como, por ejemplo, obtener una lista de archivos en un script para repetir), seguramente está utilizando la herramienta incorrecta. – Juliano

+0

@juliano - Debe ser consumido por un script python en realidad. ¿Por qué lo llamas una herramienta incorrecta? – fixxxer

+1

@fixxer En el momento en que canaliza 'ls' a python,' ls' generará un archivo por línea como expliqué en mi respuesta. –

Respuesta

245

Uso man ls para ver si su ls soporta la opción -1 (que el "uno" dígitos, no una letra minúscula "L" - @slashmais gracias), por ejemplo,

http://docs.oracle.com/cd/E19082-01/819-2239/6n4hsf6oc/index.html

...

-1

Prints one entry per line of output. 

GNU/Linux de ls lo soporta, a fin de utilizar:

ls -1a 
+4

Ah, ahora si solo cada sistema tuviera la documentación instalada ... – dty

+1

+1 No sabía acerca de -1 (-l sí (ell no uno)) Se muestra en la página de manual pero lo he estado leyendo como un todo el tiempo :) – slashmais

+0

@slashmais - Ah, buen punto - fácil de confundir. Aclaré en la respuesta. –

107

Sí:

ls -a | cat 

Explicación: El comando ls detecta si la salida es a un terminal o a un archivo o tubería y se ajusta en consecuencia.

+31

"sentidos", me gusta la palabra. Me pregunto qué '' s' piensa de las personas que lo antropomorfizan. – Chubas

+6

Brillante. Genio. Bravo. Si pudiera, te daría un máximo de cinco. Y creo que 'ls' lo considera muy bueno, ya que es un comando Bash antropomorfo muy gregario. –

+8

Tan sucio ... Brillante !! –

25

Ls está diseñado para el consumo humano, y you should not parse its output.

En los scripts de shell, hay algunos casos en los que el análisis de la salida de ls funciona es la forma más sencilla de lograr el efecto deseado. Dado que ls puede manipular caracteres no ASCII y controlar caracteres en nombres de archivos, estos casos son un subconjunto de aquellos que no requieren obtener un nombre de archivo del ls.

En python, no hay absolutamente ninguna razón para invocar ls. Python tiene toda la funcionalidad de ls incorporada. Use os.listdir para listar el contenido de un directorio y os.stat o os para obtener los metadatos del archivo. Es probable que otras funciones en los módulos os también sean relevantes para su problema.


Si accede a archivos remotos a través de SSH, una forma razonablemente robusta de la inclusión de los nombres de archivos es a través de SFTP:

echo ls -1 | sftp remote-site:dir 

Esto imprime nombre de un archivo por línea, ya diferencia de la utilidad ls, sftp no destruye los caracteres no imprimibles. Todavía no podrá listar de manera confiable los directorios donde el nombre de un archivo contiene una línea nueva, pero eso rara vez se hace (recuerde esto como un posible problema de seguridad, no como un problema de usabilidad).

en Python (ten en cuenta que metacaracteres de shell deben ser escapa en remote_dir):

command_line = "echo ls -1 | sftp " + remote_site + ":" + remote_dir 
remote_files = os.popen(command_line).read().split("\n") 

Para las interacciones más complejas, buscar el modo por lotes de SFTP en la documentación.

En algunos sistemas (Linux, Mac OS X, quizás algunos otros equipos, pero definitivamente no en Windows), un enfoque diferente es montar un sistema de archivos remoto a través de ssh con sshfs, y luego trabajar localmente.

+0

Estoy conectado a través de SSH a la máquina remota. No encontré ninguna forma de ejecutar una función python como os.listdir en la máquina remota en una sola línea. Por lo tanto, esta pregunta. No quiero escribir un script simplemente para listar archivos. ¿Hay alguna otra forma de solucionar este problema? – fixxxer

+0

@fixxxer: ssh cambia la situación, ¡es el tipo de cosas que deberías haber mencionado en tu pregunta original! Creo que sftp es apropiado para tu caso de uso. – Gilles

+0

Disculpe la confusión. ¿Hay alguna manera de insertar la contraseña en la "línea de comando" también? – fixxxer

1

Sólo por el bien de la diversidad:

ls | tr ' ' '\n' 

comando tr convierte todos los espacios en nuevas líneas. Como ls sin ningún argumento solo da nombres de archivo separados por un espacio, la salida se muestra como un nombre de archivo por línea.

+9

¡Esto es completamente peligroso! El principal trabajo de 'tr' aquí será cortar los nombres de los archivos con espacios incrustados en varias líneas. 'ls' dará como resultado un nombre de archivo por línea de todos modos cuando se conecta a otro comando. Ver http://stackoverflow.com/a/3886314/280314 –

+0

@PeterG. Sí, si tienes espacios en los nombres de los archivos, se arruinará la lista. –

4

puede utilizar ls -1

ls -l también lo hará el trabajo

1

fácil, siempre y cuando los nombres de archivo no incluyen saltos de línea:

find . -maxdepth 1 

Si está presente en otra tubería comando, probablemente debería preferir separar sus nombres de archivo por bytes nulos, en lugar de líneas nuevas, ya que los bytes nulos no pueden aparecer en un nombre de archivo (pero las líneas nuevas pueden):

find . -maxdepth 1 -print0 

La impresión de que en un terminal probablemente se muestre como una línea, porque los bytes nulos no se imprimen normalmente. Es posible que algunos programas necesiten una opción específica para manejar entradas delimitadas nulas, como sort 's -z. Su propio script de manera similar tendría que dar cuenta de esto.

Cuestiones relacionadas