¿Cómo generar solo nombres de archivo (con espacios) en ls -Al?

80

Debo repetir solo los nombres de archivos o directorios con esta construcción:

ls -Al | while read string
do
...
done

ls -Al salida:

drwxr-xr-x  12 s162103  studs         12 march 28 12:49 personal domain
drwxr-xr-x   2 s162103  studs          3 march 28 22:32 public_html
drwxr-xr-x   7 s162103  studs          8 march 28 13:59 WebApplication1

Por ejemplo si lo intento:

ls -Al | while read string
do
echo "$string" | awk '{print $9}
done

luego genera solo archivos y directorios sin espacios. Si el archivo o directorio tiene espacios como "dominio personal", será solo la palabra "personal".

Necesito una solución muy simple. Quizás haya una mejor solución que awk.

Alex Zern
fuente
2
¿Por qué no solo ls -Al *' '*? Analizar lsla salida nunca conduce a nada bueno.
manatwork
1
Si necesita algo que funcione en cualquier * nix, intente evitar usarlo ls -Al | while. Una forma simple y más confiable es for string in *; do echo "$string"; done.
forcefsck
solo necesita con esta construcción ... bueno, no es simple, ¡alguna solución!
Alex Zern
1
¿Por qué lo necesitas ls ? El análisis lsy "funciona en todo * nix y no se romperá si algo sucede" no funcionan bien juntos.
terdon

Respuestas:

99

Usted realmente no debe analizar la salida dels . Si esta es una tarea y debe hacerlo, su profesor no sabe de qué están hablando. ¿Por qué no haces algo como esto?

El bueno...

find ./  -printf "%f\n"

o

for n in *; do printf '%s\n' "$n"; done

...el malo...

Si realmente quieres usarlo ls, puedes hacerlo un poco más robusto haciendo algo como esto:

ls -lA | awk -F':[0-9]* ' '/:/{print $2}'

... y lo feo

Si insiste en hacerlo de la manera incorrecta y peligrosa y solo tiene que usar un whilebucle, haga lo siguiente:

ls -Al | while IFS= read -r string; do echo "$string" | 
    awk -F':[0-9]* ' '/:/{print $2}'; done

En serio, no lo hagas.

terdon
fuente
drwx------ 2 s162103 studs 3 oct. 9 2012 .ssh drwxr-xr-x 3 s162103 studs 6 oct. 25 09:02 .subversion drwxrwxrwt 3 s162103 studs 3 nov. 15 2012 .TempoItemsa veces tengo citas sin tiempo, solo el año y Gawk vuelven vacías
Alex Zern
1
@AlexZern Bueno, esa es una de las razones por las que no analiza el resultado ls.
terdon
2
@AlexZern, ¿por qué necesita el -linterruptor de todos modos? Si todo lo que quiere son los nombres de los archivos, simplemente ejecute ls -A. Usar -lsolo hace que tu vida sea más difícil ya que ahora tienes que analizar la salida.
terdon
porque necesito información adicional como acceso, fecha, propietario, etc. Y escribí un gran script, que funciona bien, excepto imprimir archivos y nombres de directorio con espacios.
Alex Zern
3
OK entonces. Lo que tenemos aquí es un problema XY . lsNo es la mejor manera de obtener lo que necesita. ¿Por qué no publica una nueva pregunta explicando la información que desea recopilar y podemos sugerir formas de hacerlo? Alternativamente, puede usar su script tal como está, y usar una de las sugerencias anteriores para imprimir solo el nombre. Pero en serio, no analices ls, solo dinos exactamente qué estás tratando de hacer en una nueva pregunta.
terdon
74

¿Hay alguna razón por la que ls -A1* no funcione?

P.ej:

$ touch file1 file2 file\ with\ spaces
$ ls -Al
total 0
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file1
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file2
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file with spaces
$ ls -A1
file1
file2
file with spaces
$

* Nota: esa es una letra mayúscula A y la número uno.

bahamat
fuente
44
el -1 es genio. No sabía que estaba disponible. (Lo sé, lo sé. RTFM)
The Lazy Coder
eso solo funciona para el directorio actual si desea enumerar los nombres de archivo de otro directorio, por ejemplo ~ / projects, entonces obtendrá rutas completas en lugar de nombres de archivo
thecotne
@thecotne en Mac 10.9.5 simplemente enumera los nombres de los archivos. ¿Qué sistema operativo estás usando?
AJP
estoy ejecutando este ls ~ / projects / *. sublime-project -A1 para ls ~ / projects -A1 solo obtengo nombres
thecotne
3
No se espera que @TheLazyCoder lea el manual.
c24w
41

Me pregunto por qué nadie mencionó este simple comando:

ls -a | sort
Ben
fuente
2
¡Brillante! ¿Alguna idea de cómo la canalización sorthace que el bloque de varias columnas no se divida en una sola columna?
msciwoj
@msciwoj simplemente toma las cadenas separadas por espacios en blanco y las imprime ordenadas por líneas finales
Ben
¡PERFECTO! ¿Por qué no se marcó esta como la respuesta real?
夏 期 劇場
3
Funciona aquí porque se lsrevierte a ls -1(salida de una sola columna) cuando su salida no va a una terminal (y deshabilita la cita / reemplazo de caracteres no imprimibles; @Kusalananda, lsno es compatible con POSIX si todavía lo hace). lsLa salida ya está ordenada. Por lo tanto, canalizarlo sorten el mejor de los casos no hará nada y, en el peor de los casos, alterará la salida (si los nombres de archivo contienen caracteres de nueva línea) o fallará para los nombres de archivo que no son texto. ls -a | catseria mejor. O incluso mejor ls -A1como ya se mencionó (y porque generalmente desea los reemplazos / citas cuando se muestran en una terminal)
Stéphane Chazelas
1
@ StéphaneChazelas Tomado nota. lsse comporta de manera diferente cuando la salida no es una terminal.
Kusalananda
3

No puede analizar la salida de ls, y mucho menos ls -lporque la nueva línea, al igual que el espacio es un carácter tan válido como cualquier otro en un nombre de archivo. Además, deberá tener en cuenta los enlaces simbólicos que tienen una salida como ... foo -> bar.

¿Por qué usarías de -ltodos modos si solo quieres el nombre del archivo?

Solo haz:

for file in *; do
  ...
done

Si desea incluir archivos de puntos (excepto .y ..), dependiendo del shell:

zsh:

for file in *(ND); do
  ...
done

bash:

shopt -s nullglob dotglob
for file in *; do
  ...
done

ksh93:

FIGNORE='@(.|..)'
for file in ~(N)*; do
  ...
done

POSIXY:

for file in .[!.]* ..?* *; do
  [ -e "$file" ] || [ -L "$file" ] || continue
  ...
done
Stéphane Chazelas
fuente
1

Qué tal si:

for file in * .[!.]*
do
  printf "%s\n" "$file"
done
Escrutador
fuente
1
ls -Al | tr -s ' ' | cut -f9- -d' '

comprima múltiples espacios en espacios individuales con tr, luego puede usar cortar para dividir en los campos

usuario simple
fuente
-1
ls --file *|grep ^ 

muestra qué archivos en qué directorio.

vars
fuente
No creo que esto aborde la pregunta.
Jeff Schaller