Case-insensitive sorting dalam Mac OSX

30

Bagaimana saya bisa membuat lsperintah di Max OS X Lion mengurutkan file dan direktori mirip dengan bagaimana Ubuntu Linux (case-insensitive, direktori TIDAK di atas, file dot TIDAK di atas)? Idealnya saya ingin melakukan ini tanpa mengirim output ke perintah lain seperti sort.

Misalnya, saya ingin melihat:

foo
Foobar
MyStuff/
.stuff/
test.txt

dari pada:

.stuff
Foobar
MyStuff/
foo
test.txt

Di Linux, lspengurutan urutan dikendalikan oleh lokal sistem, khususnya LC_COLLATE. Kapan LC_COLLATE=en_US.UTF-8, ls akan mengurutkan item seperti yang saya inginkan. Kapan LC_COLLATE=C, lsakan mengurutkan mirip dengan OS X.

LC_COLLATEdiatur ke en_US.UTF-8dalam OS X, tetapi lsmasih menyortir dengan POSIXcara lama . Adakah yang tahu bagaimana saya bisa membuat ini berperilaku lebih seperti Linux?

Emil
sumber
Jika itu membantu: apple.stackexchange.com/a/22304/8546 mengamati bahwa HFS Plus biasanya dikonfigurasikan sebagai case-insensitive tetapi menjaga case .
Graham Perrin

Jawaban:

16

Itu tidak mungkin:

Melihat kode sumber untuk ls , ia menggunakan strcoll untuk mengurutkan nama file, dan karenanya harus menghormati LC_COLLATE.

Beberapa posting online menunjukkan bahwa lokal di BSD (dan Darwin / OS X) agak rusak dibandingkan dengan yang ada di Linux. Saya menulis program penyortiran cepat saya sendiri yang secara eksplisit mengatur lokal itu dan mengujinya menggunakan lokal en_US.UTF-8 dan C pada mesin saya (Mac OS 10.6.3) dan mesin universitas (Linux, FC11?). Sementara penyortiran berfungsi seperti yang diharapkan pada mesin linux, ("a B c" vs "B a c"), mac selalu mengurutkannya sebagai "B a c".

Sumber: http://ask.metafilter.com/130292/CaseInsensitive-LS-on-Mac-OS-X

JAWABAN ASLI

Perintah ini tidak mengurutkan file dot, tetapi menunjukkan daftar direktori tambahan

ls -f1 

Saya mendekati ini:

.
..
.stuff
foo
Foobar
MyStuff
test.txt
Sairam
sumber
1
Menarik bahwa "semacam penonaktifan" dengan opsi -f tampaknya mengurutkannya seperti yang diharapkan. Saya berasumsi ini adalah entri filesystem / HFS + sortasi dengan pemeriksaan yang lebih "alami".
Gerry
6

Saya tahu ini telah dijawab tetapi ini bekerja paling baik untuk saya:

ls -f1 -alF -G

Ini mencantumkan semua detail dan mengurutkannya dengan mengabaikan case.

Jared Burrows
sumber
4

Ini telah mengganggu saya untuk sementara waktu sekarang, dan akhirnya saya bereskan (heh). Setelah mencoba banyak saran yang tidak berhasil, inilah yang berhasil.

Jika Anda ingin menginstal MacPorts (atau Homebrew, atau Fink), versi ls GNU melakukan apa yang Anda inginkan. Saya menggunakan MacPorts sendiri, jadi itulah pendekatan yang akan saya jelaskan:

  1. Unduh dan pasang MacPorts:

    http://www.macports.org

  2. Instal paket GNU Coreutils:

    sudo port install coreutils

  3. Anda sekarang harus memiliki GNU ls: gls. Cobalah di direktori yang berisi item yang dimulai dengan huruf besar dan kecil:

    gls -U

    ( -UOpsi ini sebenarnya berarti "tidak disortir", tetapi pada OS X yang memiliki efek yang diinginkan membuatnya tidak sensitif huruf.)

  4. Tambahkan alias ini di Anda .bash_profilesehingga reguler lsakan bekerja seperti yang Anda inginkan (saya suka keluaran warna, tetapi Anda dapat menghilangkannya jika Anda mau; Anda hanya perlu -U):

    alias ls='gls -U --color'

Perhatikan bahwa -Uopsi ini mungkin tidak akan berfungsi pada platform lain. Pada OS X, sepertinya selalu melakukan hal yang benar (mungkin karena HFS + secara efektif case-insensitive - "case-aware", secara teknis), tetapi jika Anda mencobanya pada kotak Linux, hasilnya kemungkinan besar tidak akan diurutkan sama sekali.

Jason Sims
sumber
1
3. tampaknya tidak memiliki efek samping yang diinginkan lagi (opsi -U) di bawah macOS> = 10.13 karena APFS baru.
Marius Hofert
1
Yap ... sepertinya tidak ada cara untuk melakukan ini dengan APFS.
Jason Sims
Konfirmasi berhasil pada 10.12. Terima kasih!
Kolonel Panic
4

Menambah apa yang Mike tulis di atas, saya telah mengambilnya sedikit lebih jauh dan menemukan cara untuk mendefinisikan aturan pemeriksaan Anda sendiri.

Definisi lokal terletak di / usr / share / locale /. Setiap folder adalah lokal dan memiliki file (atau tautan) LC_COLLATE, yang mendefinisikan simbol mana yang "sama" (misalnya, bahwa U, u dan ü harus dianggap sama ketika memesan). Anda dapat menduplikasi direktori dan ini akan membuat definisi lokal baru:

$ sudo cp -R en_GB.UTF-8/ en_GB.UTF-8-CI/

Sekarang Anda akan memiliki lokal baru yang disebut 'en_GB.UTF-8-CI' ('CI' untuk case-sensitive) dan Anda dapat menggunakan LC_COLLATE dari sana.

Sekarang, untuk mengubah LC_COLLATE di lokal baru Anda dapat mengunduh sumber-sumber lokal dari http://www.opensource.apple.com/source/adv_cmds/adv_cmds-119/usr-share-locale.tproj/colldef/ , edit satu itulah yang paling dekat dengan apa yang Anda inginkan dan jalankan

$ colldef < <new collation file>
$ sudo cp LC_COLLATE /usr/share/locale/en_GB.UTF-8-CI/

dan sekarang saat Anda berlari

$ LC_COLLATE=en_GB.UTF-8-CI ls

Anda harus menyortir sesuai aturan Anda .

Ya, inilah yang diperlukan untuk membuat 'ls' semacam tidak sensitif huruf.

Dmitry
sumber
2

Sebagai solusinya, Anda dapat menggunakan fungsi dan alias:

function lssorted() { /bin/ls "$@" | sort -f ;}
alias ls='lssorted'

Ini menghasilkan case yang diurutkan secara tidak sensitif keluaran untuk perintah ls standar.

Arne
sumber
1
Saya harus perhatikan: ini akan gagal jika misalnya -l digunakan. Kemudian ls menghasilkan baris lain "total X" di awal, yang juga akan diurutkan.
Arne
2

Menggunakan

ls -f

bekerja untukku.

-f secara resmi mematikan penyortiran apa pun, tetapi sepertinya jenis HFS asli bersinar, yang merupakan jenis case-insensitive.

Saya kira, itu benar-benar tergantung pada apakah Anda memiliki case-sensitive HD yang diformat atau tidak, tetapi karena format HFS case-INsensitive adalah default untuk disk sistem Mac OS X, ini seharusnya bekerja untuk sebagian besar pengguna.

Jpsy
sumber
Ini jelas jawaban yang tepat. Satu-satunya masalah dengan itu adalah bahwa ia secara implisit juga mengaktifkan -a, dan tidak ada cara untuk mematikannya, yang akan menampilkan file / folder yang dimulai dengan titik, termasuk. dan ...
lensovet
1
Masalah lainnya (sekarang) adalah bahwa ini sepertinya tidak berfungsi lagi di bawah macOS> = 10.13 karena APFS baru.
Marius Hofert
1

Terinspirasi oleh jawaban Mike, saya menambahkan yang berikut ke / etc / bashrc, dan itu berfungsi dengan baik di Mojave. Ini daftar file tersembunyi di akhir ketika -a ditambahkan, tapi itu tidak mengganggu saya.

export LC_COLLATE="cs_CZ.ISO8859-2"; alias ls='ls -lhFG'

Anda dapat melihat konfigurasi baru dengan menjalankan perintah lokal. Untuk kembali, cukup hapus baris dari / etc / bashrc dan masuk kembali ke terminal.

$ locale
LANG="en_US.UTF-8"
LC_COLLATE="cs_CZ.ISO8859-2"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL=

Perhatikan bahwa baik ls-f1 maupun ls -f tidak bekerja untuk saya di Mojave. Saya berakhir dengan daftar yang benar-benar tidak disortir. Hanya solusi yang saya berikan yang bekerja untuk saya di Mojave.

Yer
sumber
Jawaban terbaik, tetapi contoh yang diberikan tidak terlalu banyak. Ini harus dipangkas ke: masukkan baris berikut ke .bashrcatau .zshrc:alias ls="LC_COLLATE=cs_CZ.ISO8859-2 ls"
user1561489
0

Menjalankan:

$ type ls

Anda mungkin akan menemukan bahwa lsperintah Anda adalah alias.

MikeyB
sumber
Pada linux: ls is /bin/ls. Pada OS X: ls is hashed (/bin/ls). Either way, bahkan jika saya menelepon /bin/lslangsung masih tidak mengurutkan menurut LC_COLLATE.
2
Itu mengejutkan, saya akan bertaruh bahwa lsperintah Anda alias dimasukkan --group-directories-first. Mungkin masih dilakukan di tempat lain, hanya saja bukan alias.
MikeyB
0

Jika Anda terutama mementingkan urutan sortir file dot, Anda dapat mengurutkan berdasarkan ekstensi : Gunakan lsperintah dari GNU Fileutils dengan opsi --sort=extension. (Anda dapat menginstal GNU Fileutils misalnya melalui macports.)

halo
sumber
0

ls sedang mengurutkan berdasarkan LC_COLLATE, hanya saja sebagian besar file LC_COLLATE diatur untuk melakukan penyortiran peka huruf besar-kecil. http://collation-charts.org/fbsd54/

Ada dua yang ditetapkan untuk penyortiran case sensitif: cs_CZ.ISO8859-2 dan et_EE.ISO8859-15 et_EE.ISO8859.15 tidak mengurutkan "Z" seperti yang diinginkan oleh penutur bahasa Inggris. cs.CZ.ISO8859-15 melakukan pekerjaan yang baik dengan alfabet, saya hanya berharap itu akan mengurutkan "~" sebelum karakter alfabet.

Solusi saya adalah: LC_COLLATE = cs_CZ.ISO8859-2 / bin / ls -FG

Saya ingin tahu apakah file LC_COLLATE khusus dapat dibuat untuk menangani "." seperti yang Anda inginkan dan "~" seperti yang saya inginkan.

Mike
sumber