Haga que ls lo imprima todo en una línea (como en la terminal)

14

ls imprime de manera diferente dependiendo de si la salida es a un terminal o a otra cosa.

p.ej:

$ ls .
file1  file2
$ ls . | head
file1
file2

¿Hay alguna forma de lsimprimir en una línea como si fuera un terminal cuando no lo es? Hay un -Cargumento que dice que hace eso, pero lo dividirá en varias líneas.

$ ls
file1  file10  file11  file12  file13  file14  file15  file16  file17  file18  file19 file2  file3  file4  file5  file6  file7  file8  file9
$ ls -C . | head
file1 file11 file13 file15 file17 file19 file3  file5  file7  file9
file10 file12 file14 file16 file18 file2 file4  file6  file8

La razón por la que quiero hacer esto es porque quiero monitorear los archivos en un directorio que estaban cambiando rápidamente. Había construido esta simple línea de comando:

while [[ true ]] ; do ls ; done | uniq

El uniq evita que envíe spam a mi terminal y solo muestre cambios. Sin embargo, estaba imprimiendo todo en diferentes líneas de red, lo que hacía que el uniq fuera inútil y aumentaba la cantidad de ruido. En teoría, se podría usar watchpara esto, pero quería ver un archivo tan pronto como apareció / desapareció.

Esta es la solución final:

while [[ true ]] ; do ls | tr '\n' ' ' ; done | uniq
Rory
fuente
44
si está canalizando ls a otro comando, está haciendo algo mal. ¿Qué estás tratando de lograr realmente?
Justin
Justin, he actualizado la pregunta con una explicación.
Rory

Respuestas:

16

No conozco un interruptor que pueda hacer eso, pero puedes canalizar tu salida trpara hacerlo:

ls | tr "\n" " " | <whatever you like>
cristiano
fuente
16
ls | xargs

A mí me funciona, es la forma más sencilla que he encontrado. Espero que esto también te ayude.

Jian Weihang
fuente
4

Si lstiene esta opción, puede usar un valor alto y puede hacer lo que quiera:

ls -w 10000 -C . | head
Pausado hasta nuevo aviso.
fuente
4

ah, ahora que has actualizado la pregunta ...

while true ; do echo * ; done | uniq

hará lo que publicaste, simplemente más simple.

sin embargo, es mejor usar algo que use inotify para hacer esto ... como

inotifywait -m . -e create,delete

si no tiene inotify, entonces algo como esto también funciona bien:

import os
import time

last = set()
while True:
    cur = set(os.listdir('.'))
    added = cur-last
    removed = last-cur
    if added: print 'added', added
    if removed: print 'removed', removed
    last = set(os.listdir('.'))
    time.sleep(0.1)
Justin
fuente
3

¿Qué pasa con lo bastante trivial?

echo *

? :-) Ni siquiera necesitas bifurcarlo. :-)

peterh - Restablece a Monica
fuente
0

Esto puede ser lo que está buscando, pero es posible que haya entendido mal su pregunta, pero aquí va :)

Algunos comandos que vale la pena considerar:

watch - ejecuta un programa periódicamente, mostrando xargs de pantalla completa de salida - construye y ejecuta líneas de comando desde la entrada estándar (-0 si quieres manejar archivos con espacios, etc.)

Puede hacer algo como lo siguiente para mostrar los últimos 10 archivos / directorios que cambiaron con un intervalo de 2 segundos (predeterminado para ver)

ver "ls -lart | tail -10"

las opciones -lart le dicen a ls que sea detallado y que se clasifique según el tiempo de modificación.

Si realmente solo quieres los archivos, simplemente haría algo como:

ver "ls -lart | awk '{print \ $ 8}' | tail -10 | xargs"

o simplemente para mostrarlos:

ls -lart | awk '{print $ 8}' | cola -10 | xargs

ScottZ
fuente
0

Puede usar ticks en el shell para lograr esto como:

echo -E `ls -1`
polluelos
fuente
No funciona con todos los nombres de archivo. Probar:touch ./-en
kasperd
Eso solo importa si no tiene archivos que comiencen con [a-d]ese tipo antes. Si lo está ejecutando en un script echo -E, no sería demasiado inconveniente y la nueva línea final puede no importar.
pollitos
0

Esto funcionó para mí porque no solo necesitaba imprimir el resultado en una línea, sino que también necesitaba especificar cómo debía separarse y puede especificarlo con ORS

ls -1 | awk '{ ORS="|"; print; }'
mavi
fuente