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.