Come posso elencare un nome file per riga di output in Linux?


229

Sto usando il ls -acomando per ottenere i nomi dei file in una directory, ma l'output è in una sola riga.

Come questo:

.  ..  .bash_history  .ssh  updater_error_log.txt

Ho bisogno di un'alternativa integrata per ottenere i nomi dei file, ognuno su una nuova riga, in questo modo:

.  
..  
.bash_history  
.ssh  
updater_error_log.txt

3
Si intende visualizzare un elenco per il consumo umano. Se stai usando ls per qualsiasi altro scopo (come, diciamo, per ottenere un elenco di file in uno script su cui iterare), sicuramente stai usando lo strumento sbagliato.
Juliano,

2
@juliano - In realtà deve essere consumato da uno script Python. Perché lo chiami uno strumento sbagliato?
fixxxer,

1
@fixxer Nel momento in cui esegui il pipe lssu Python, lsverrà generato un file per riga, come ho spiegato nella mia risposta.
Peter G.

6
@fixxxer: Quindi lo stai usando in modo errato. Formatta l'elenco per l'output nel terminale utente. Può sostituire caratteri speciali nel nome file, può omettere caratteri che hanno un significato speciale, ecc ... In altre parole, formatta un elenco per l'utente. Vuoi nomi di file non formattati. Qualche motivo speciale per cui non stai usando il modulo 'glob' di Python? docs.python.org/library/glob.html Ci sono anche 'fnmatch', 'dircache' e altri.
Juliano,

@fixxer Hai effettivamente creato lsl'output pythone osservato l'output a riga singola in Python?
Peter G.

Risposte:


430

Usa l' -1opzione (nota che questa è una "una" cifra, non una lettera minuscola "L"), in questo modo:

ls -1a

Per prima cosa, assicurati dei tuoi lssupporti -1. Coreutils GNU (installati su sistemi Linux standard) e Solaris; ma in caso di dubbi, utilizzare man lso ls --helpo controllare la documentazione. Per esempio:

$ man ls
...
       -1     list one file per line.  Avoid '\n' with -q or -b

2
+1 Non sapevo di -1 (-l si (ell non uno)) Viene mostrato nella pagina man ma l'ho letto come un ell per tutto il tempo :)
slashmais

@slashmais - Ah, buon punto - facile da confondere. Ho chiarito nella risposta.
Bert F

1
@dty: per GNU, questo viene documentato in ls --helpoutput ... sempre installato ;-)
Tony Delroy,

3
Ho cercato su Google linux ls one file per linee questo è stato l'articolo principale. Non riesco a credere a quanto sia prolifica la risposta scelta o che questa risposta abbia meno voti di quella che convoglia al gatto. ls -1FTW.
crantok,

3
lsil -1comportamento predefinito è quando l'uscita non è collegata al terminale.
codeforester

132

Sì, puoi facilmente creare lsun nome file per riga:

ls -a | cat

Spiegazione: Il comando lsrileva se l'output è su un terminale o su un file o pipe e si adatta di conseguenza.

Quindi, se esegui il pipe ls -asu Python, dovrebbe funzionare senza alcuna misura speciale.


2
Caspita, è geniale. Il vantaggio rispetto alla risposta accettata - questa in realtà funziona su Android / shell adb - dove lsc'è solo una versione ridotta quindi non supporta-1
mkilmanas

Come si eviterebbe la .e .."file" che mostrano in uscita però?
matanster

@matanster: dipende, vuoi vedere i file dot? In caso contrario, basta rilasciare l'opzione -a.
Peter G.

29

Ls è progettato per il consumo umano e non dovresti analizzarne l'output .

Negli script di shell, ci sono alcuni casi in cui l'analisi dell'output di ls funziona è il modo più semplice per ottenere l'effetto desiderato. Poiché ls potrebbe manipolare caratteri non ASCII e controllare i caratteri nei nomi dei file, questi casi sono un sottoinsieme di quelli che non richiedono l'ottenimento di un nome file da ls.

In Python, non c'è assolutamente alcun motivo per invocare ls. Python ha tutte lsle funzionalità integrate. Utilizzare os.listdirper elencare il contenuto di una directory e os.stato osper ottenere metadati di file. osÈ probabile che anche altre funzioni nei moduli siano rilevanti per il tuo problema.


Se stai accedendo a file remoti su ssh, un modo ragionevolmente efficace per elencare i nomi dei file è tramite sftp:

echo ls -1 | sftp remote-site:dir

Questo stampa un nome file per riga e, diversamente lsdall'utilità, sftpnon manipola i caratteri non stampabili. Non sarai ancora in grado di elencare in modo affidabile le directory in cui un nome file contiene una nuova riga, ma ciò avviene raramente (ricordalo come un potenziale problema di sicurezza, non un problema di usabilità).

In python (attenzione che i metacaratteri della shell devono essere in escape remote_dir):

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

Per interazioni più complesse, cercare la modalità batch di sftp nella documentazione.

Su alcuni sistemi (Linux, Mac OS X, forse alcuni altri unices, ma sicuramente non Windows), un approccio diverso è montare un filesystem remoto tramite ssh con sshfs e quindi lavorare localmente.


Sono collegato tramite SSH alla macchina remota. Non ho trovato alcun modo per eseguire una funzione Python come os.listdir sul computer remoto in una sola riga. Quindi, questa domanda. Non voglio scrivere uno script per elencare semplicemente i file. Esiste un altro modo per aggirare questo problema?
fixxxer,

@fixxxer: ssh cambia la situazione, è il genere di cose che avresti dovuto menzionare nella tua domanda originale! Penso che sftp sia appropriato per il tuo caso d'uso.
Gilles 'SO- smetti di essere malvagio'

Mi dispiace per la confusione. C'è un modo in cui posso inserire la password anche nella "linea_comando"?
fixxxer,

@fixxxer: Non lo so, gli autori di ssh aggrottano le sopracciglia sulle password archiviate in testo semplice e tendono a non renderlo facile. Dovresti davvero impostare l'autenticazione basata su chiave (ci sono molti tutorial sul web e domande su superuser.com al riguardo).
Gilles 'SO- smetti di essere malvagio'

11

Puoi usare ls -1

ls -l farà anche il lavoro


La risposta principale menziona già esattamente le cose che hai detto. anche la domanda specifica dice ls -lche non dovrebbe essere usato.
DevX,

2

Semplice, purché i nomi dei file non includano le nuove righe:

find . -maxdepth 1

Se stai eseguendo il piping di questo in un altro comando, probabilmente dovresti preferire separare i nomi dei file da byte null, piuttosto che newline, poiché i byte null non possono verificarsi in un nome file (ma i newline potrebbero):

find . -maxdepth 1 -print0

La stampa che su un terminale verrà probabilmente visualizzata come una riga, poiché normalmente i byte null non vengono stampati. Alcuni programmi potrebbero richiedere un'opzione specifica per gestire input delimitati da null, come sort's -z. Allo stesso modo il tuo script dovrebbe tener conto di questo.

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.