Bagaimana cara membuat daftar satu nama file per baris output di Linux?

229

Saya menggunakan ls -aperintah untuk mendapatkan nama file dalam direktori, tetapi hasilnya dalam satu baris.

Seperti ini:

.  ..  .bash_history  .ssh  updater_error_log.txt

Saya memerlukan alternatif bawaan untuk mendapatkan nama file, masing-masing pada baris baru, seperti ini:

.  
..  
.bash_history  
.ssh  
updater_error_log.txt
fixxxer
sumber
3
Itu dimaksudkan untuk menampilkan daftar untuk konsumsi manusia. Jika Anda menggunakan ls untuk tujuan lain (seperti, katakanlah, untuk mendapatkan daftar file dalam skrip untuk beralih lagi), Anda pasti menggunakan alat yang salah.
Juliano
2
@ juliano - Ini harus dikonsumsi oleh skrip python sebenarnya. Mengapa Anda menyebutnya alat yang salah?
fixxxer
1
@ fixxer Saat Anda melakukan pipe lske python, lsakan menampilkan satu file per baris seperti yang saya jelaskan dalam jawaban saya.
Peter G.
6
@ fixxxer: Maka Anda memang menggunakannya dengan salah. Ini memformat daftar untuk output di terminal pengguna. Itu dapat menggantikan karakter khusus dalam nama file, itu dapat menghilangkan karakter yang memiliki arti khusus, dll ... Dengan kata lain, ls memformat daftar ke pengguna. Anda ingin nama file yang tidak diformat. Adakah alasan khusus mengapa Anda tidak menggunakan modul python 'glob'? docs.python.org/library/glob.html Ada juga 'fnmatch', 'dircache' dan lainnya.
Juliano
@ fixxer Sudahkah Anda benar-benar membuat lsoutput ke pythondan mengamati output single-line di python?
Peter G.

Jawaban:

430

Gunakan -1opsi (perhatikan ini digit "satu", bukan huruf kecil "L"), seperti ini:

ls -1a

Namun, pertama-tama, pastikan lsdukungan Anda -1. GNU coreutils (diinstal pada sistem Linux standar) dan Solaris lakukan; tetapi jika ragu, gunakan man lsatau ls --helpatau periksa dokumentasi. Misalnya:

$ man ls
...
       -1     list one file per line.  Avoid '\n' with -q or -b
Bert F
sumber
2
+1 Saya tidak tahu tentang -1 (-l ya (ell bukan satu)) Itu muncul di halaman manual tapi saya sudah membacanya sebagai ell sepanjang waktu :)
slashmais
@slashmais - Ah, poin bagus - mudah salah. Saya mengklarifikasi jawabannya.
Bert F
1
@dty: untuk GNU, Anda mendapatkan ini didokumentasikan dalam ls --helpoutput ... selalu diinstal ;-)
Tony Delroy
3
Dicari di Google untuk linux ls one file per linedan ini adalah artikel teratas. Tidak dapat percaya betapa bertele-tele jawaban yang dipilih adalah atau bahwa jawaban ini memiliki lebih sedikit suara daripada yang menyumbang. ls -1ftw.
crantok
3
lsdefault ke -1perilaku ketika output tidak terhubung ke terminal.
codeforester
132

Ya, Anda dapat dengan mudah membuat lsoutput satu nama file per baris:

ls -a | cat

Penjelasan: Perintah lsmerasakan jika output ke terminal atau ke file atau pipa dan menyesuaikan sesuai.

Jadi, jika Anda mem ls -a- pipe ke python, ia seharusnya bekerja tanpa tindakan khusus.

Peter G.
sumber
2
Wow, ini brilian. Keuntungan atas jawaban yang diterima - yang ini benar-benar berfungsi pada Android / adb shell - di mana lshanya beberapa versi yang tidak didukung sehingga tidak mendukung-1
mkilmanas
Bagaimana Anda menghindari .dan .."file" yang ditampilkan di output?
matanster
@ matanster: Tergantung, apakah Anda ingin melihat file-dot sama sekali? Jika tidak, jatuhkan saja opsi -a.
Peter G.
29

Ls dirancang untuk konsumsi manusia, dan Anda tidak boleh menguraikan hasilnya .

Dalam skrip shell, ada beberapa kasus di mana parsing output ls berfungsi adalah cara paling sederhana untuk mencapai efek yang diinginkan. Karena ls dapat membuat non-ASCII dan mengontrol karakter dalam nama file, case-case ini adalah himpunan bagian dari mereka yang tidak memerlukan untuk mendapatkan nama file dari ls.

Dalam python, sama sekali tidak ada alasan untuk memohon ls. Python memiliki semua lsfungsionalitas bawaan. Gunakan os.listdiruntuk membuat daftar isi direktori dan os.statatau osuntuk mendapatkan metadata file. Fungsi lain dalam osmodul juga mungkin relevan dengan masalah Anda.


Jika Anda mengakses file jarak jauh melalui ssh, cara daftar nama file yang cukup kuat adalah melalui sftp:

echo ls -1 | sftp remote-site:dir

Ini mencetak satu nama file per baris, dan tidak seperti lsutilitas, sftptidak membuat karakter yang tidak dapat dicetak . Anda masih tidak dapat membuat daftar direktori dengan andal di mana nama file berisi baris baru, tapi itu jarang dilakukan (ingat ini sebagai masalah keamanan potensial, bukan masalah kegunaan).

Dengan python (berhati-hatilah bahwa karakter meta shell harus lolos remote_dir):

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

Untuk interaksi yang lebih kompleks, lihat mode batch sftp dalam dokumentasi.

Pada beberapa sistem (Linux, Mac OS X, mungkin beberapa unix lain, tapi jelas bukan Windows), pendekatan yang berbeda adalah memasang sistem file jarak jauh melalui ssh dengan sshfs , dan kemudian bekerja secara lokal.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Saya terhubung melalui SSH ke mesin jarak jauh. Saya tidak menemukan cara untuk menjalankan fungsi python seperti os.listdir pada mesin jarak jauh dalam satu baris. Karenanya, pertanyaan ini. Saya tidak ingin menulis skrip untuk sekadar daftar file. Apakah ada cara lain untuk mengatasi masalah ini?
fixxxer
@ fixxxer: ssh memang mengubah situasi, itu adalah hal-hal yang seharusnya Anda sebutkan dalam pertanyaan awal Anda! Saya pikir sftp sesuai untuk kasus penggunaan Anda.
Gilles 'SANGAT berhenti menjadi jahat'
Saya minta maaf atas kebingungannya. Apakah ada cara saya dapat memasukkan kata sandi di "command_line" juga?
fixxxer
@ fixxxer: Saya tidak tahu, penulis ssh mengerutkan kening pada kata sandi yang disimpan dalam teks biasa dan cenderung tidak membuat ini mudah. Anda harus benar-benar mengatur otentikasi berbasis kunci (ada banyak tutorial di web dan pertanyaan tentang superuser.com tentang ini).
Gilles 'SANGAT berhenti menjadi jahat'
11

kamu bisa memakai ls -1

ls -l juga akan melakukan pekerjaan

ILF
sumber
Jawaban teratas sudah menyebutkan hal-hal persis yang Anda katakan. juga pertanyaan yang secara spesifik mengatakan ls -ltidak boleh digunakan.
DevX
2

Mudah, asalkan nama file Anda tidak menyertakan baris baru:

find . -maxdepth 1

Jika Anda mem-pipkan ini ke perintah lain, Anda mungkin sebaiknya memilih nama file Anda dengan null bytes, daripada baris baru, karena null byte tidak dapat terjadi dalam nama file (tetapi baris baru mungkin):

find . -maxdepth 1 -print0

Mencetak pada terminal mungkin akan ditampilkan sebagai satu baris, karena null byte biasanya tidak dicetak. Beberapa program mungkin memerlukan opsi khusus untuk menangani masukan nol-koma, seperti sort's -z. Skrip Anda sendiri juga perlu menjelaskan hal ini.

8bree
sumber