Come produrre solo nomi di file (con spazi) in ls -Al?


80

Dovrei fare eco solo ai nomi di file o directory con questa costruzione:

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

ls -Al produzione :

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

Ad esempio se provo:

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

quindi emette solo file e directory senza spazi. Se il file o la directory hanno spazi come "dominio personale" sarà solo la parola "personale".

Ho bisogno di una soluzione molto semplice. Forse c'è una soluzione migliore di Awk.


2
Perché non solo ls -Al *' '*? L' lsoutput di analisi non porta mai a nulla di buono.
arte

1
Se hai bisogno di qualcosa che funzioni in qualsiasi * nix, prova a evitare di usarlo ls -Al | while. Un modo semplice e più affidabile è for string in *; do echo "$string"; done.
forcefsck

serve solo con questa costruzione..bene, non semplice, qualsiasi soluzione!
Alex Zern,

1
Perché avete bisogno ls ? L'analisi lse "funziona in tutto * nix e non si romperà se succede qualcosa" non vanno bene insieme.
terdon

Risposte:


99

Non dovresti davvero analizzare l'output dils . Se questo è un compito a casa e sei tenuto a farlo, il tuo professore non sa di cosa stanno parlando. Perché non fai qualcosa del genere:

Il bene...

find ./  -printf "%f\n"

o

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

...il cattivo...

Se vuoi davvero usarlo ls, puoi renderlo un po 'più robusto facendo qualcosa del genere:

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

... e il brutto

Se insisti a farlo nel modo sbagliato e pericoloso e whiledevi solo usare un ciclo, fai questo:

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

Scherzi a parte, semplicemente no.


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 volte ho una data senza tempo, solo anno e ritorno gawk vuoto
Alex Zern

1
@AlexZern Bene, questo è uno dei motivi per cui non analizzi l'output ls.
terdon

2
@AlexZern perché hai bisogno -ldell'interruttore? Se vuoi solo i nomi dei file, esegui ls -A. L'uso -lrende solo la vita più difficile poiché ora devi analizzare l'output.
terdon

perché ho bisogno di ulteriori informazioni come accesso, data, proprietario, ecc. E ho scritto un enorme script, che funziona bene, tranne i file di stampa e i nomi delle directory con spazi.
Alex Zern,

3
Va bene allora. Quello che abbiamo qui è un problema XY . lsnon è il modo migliore per ottenere ciò di cui hai bisogno. Perché non pubblichi una nuova domanda che spieghi le informazioni che vuoi raccogliere e possiamo suggerire modi per farlo. In alternativa, puoi utilizzare lo script così com'è e utilizzare uno dei suggerimenti sopra riportati per stampare solo il nome. Ma seriamente, non analizzare ls, dicci esattamente cosa stai cercando di fare in una nuova domanda.
terdon

74

C'è qualche motivo per cui ls -A1* non funziona?

Per esempio:

$ 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: questa è la lettera maiuscola A e il numero uno.


4
il -1 è geniale. Non sapevo che fosse disponibile. (Lo so lo so. RTFM)
The Lazy Coder

che funziona solo per la directory corrente se si desidera elencare i nomi dei file da altre directory dire ~ / progetti, si otterranno percorsi completi invece dei nomi dei file
thecotne,

@thecotne su Mac 10.9.5 elenca solo i nomi dei file. Quale sistema operativo stai usando?
AJP

sto eseguendo questo ls ~ / projects / *. sublime-project -A1 per ls ~ / projects -A1 ottengo solo nomi
thecotne

3
@TheLazyCoder non dovrebbe leggere il manuale.
24

41

Mi chiedo perché nessuno abbia menzionato questo semplice comando:

ls -a | sort

2
Brillante! Qualche idea su come il piping sortprovochi il blocco di più colonne in modo che non sia imperniato in una singola colonna?
msciwoj,

@msciwoj prende semplicemente tutte le stringhe separate da spazi bianchi e le stampa ordinate separate da linee di fondo
Ben

PERFETTO! Perché questa non è stata contrassegnata come la vera risposta !?
夏 期 劇場

3
Funziona qui perché lsritorna a ls -1(output a colonna singola) quando il suo output non va a un terminale (e disabilita la quotazione / sostituzione dei caratteri non stampabili; @Kusalananda, lsse non lo fa ancora non è conforme a POSIX). lsl'output è già ordinato. Quindi, eseguirne il piping sortnella migliore delle ipotesi non farà nulla, e nel peggiore dei casi manomettere l'output (se i nomi dei file contengono caratteri di nuova riga) o fallire per i nomi di file che non sono testo. ls -a | catsarebbe meglio. O ancora meglio ls -A1come già accennato (e poiché generalmente si desidera che i ricambi / le citazioni vengano visualizzati su un terminale)
Stéphane Chazelas

1
@ StéphaneChazelas Noted. lssi comporta diversamente quando l'output non è un terminale.
Kusalananda

3

Non è possibile analizzare l'output di ls, figuriamoci ls -lperché newline, proprio come lo spazio è un carattere valido come qualsiasi in un nome file. Inoltre, dovrai considerare i collegamenti simbolici che hanno un output simile ... foo -> bar.

Perché dovresti usare -lcomunque se desideri solo il nome del file?

Basta fare:

for file in *; do
  ...
done

Se si desidera includere file dot (tranne .e ..), a seconda della 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

POSIXly:

for file in .[!.]* ..?* *; do
  [ -e "$file" ] || [ -L "$file" ] || continue
  ...
done

1

Che ne dite di:

for file in * .[!.]*
do
  printf "%s\n" "$file"
done

1
ls -Al | tr -s ' ' | cut -f9- -d' '

comprimere più spazi in singoli spazi con tr, quindi è possibile utilizzare il taglio per dividere i campi




-1
ls --file *|grep ^ 

visualizza quali file in quale directory.


Non penso che questo affronti la domanda.
Jeff Schaller
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.