ฉันจะทำให้“ ls” แสดงดอทไฟล์ได้อย่างไรในขณะที่ไม่สนใจตัวพิมพ์เล็กและตัวพิมพ์ใหญ่?


21

สร้างไฟล์ต่อไปนี้ในไดเรกทอรี

$ touch .a .b a b A B 你好嗎

lsคำสั่งซื้อเริ่มต้นของฉันเพิกเฉยต่อการมีจุดนำอยู่รวมกับไฟล์อื่น ๆ

$ ls -Al
total 0
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 a
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 .a
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 A
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 b
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 .b
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 B
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:06 你好嗎

ฉันสามารถ เปลี่ยน LC_COLLATEเพื่อใส่ dotfiles ก่อน

$ LC_COLLATE=C ls -Al
total 0
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 .a
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 .b
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 A
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 B
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 a
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 b
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:06 你好嗎

แต่น่าเสียดายที่นี้จะทำให้การจัดเรียงคำสั่งกรณีที่สำคัญคือAและBPrecede และa bมีวิธีการพิมพ์ dotfiles แรกในขณะที่อยู่กรณีตาย (กAและaPrecede Bและb)?

แก้ไข: พยายามแก้ไข LC_COLLATE

ไม่มีคำตอบใดที่จำลองฟังก์ชันการทำงานlsได้อย่างง่ายดาย เป็นไปได้ว่าฉันสามารถห่อบางส่วนของพวกเขาในฟังก์ชั่น แต่นี้จะต้องมีรหัสรายละเอียดบางอย่างเกี่ยวกับวิธีการทำงานกับไม่มีข้อโต้แย้งเทียบกับการจัดหาไดเรกทอรีเป็นอาร์กิวเมนต์ หรือวิธีจัดการกับการ-dตั้งค่าสถานะที่ชัดเจน

หรือฉันคิดว่าบางทีอาจจะดีกว่าLC_COLLATEที่จะใช้ อย่างไรก็ตามฉันไม่สามารถทำงานได้ LC_COLLATE="en_AU.UTF-8"ฉันกำลังใช้ ฉันตรวจสอบแล้ว/usr/share/i18n/locales/en_AU(ถึงแม้ว่าฉันไม่แน่ใจว่านี่เป็นไฟล์ที่ถูกต้องหรือไม่เนื่องจากฉันไม่เห็นข้อมูลอ้างอิงUTF-8) ฉันพบสิ่งต่อไปนี้

LC_COLLATE
copy "iso14651_t1"
END LC_COLLATE

/usr/share/i18n/locales/iso14651_t1copy "iso14651_t1_common"มี ในที่สุดก็/usr/share/i18n/locales/iso14651_t1_commonมี

 <U002E> IGNORE;IGNORE;IGNORE;<U002E> # 47 .

ฉันลบบรรทัดนี้วิ่งsudo locale-genและรีสตาร์ทคอมพิวเตอร์ น่าเสียดายที่มันไม่มีอะไรเปลี่ยนแปลง

คำตอบ:


11

OP ใกล้เคียงกับการแก้ไข/usr/share/i18n/locales/iso14651_t1_commonแต่เคล็ดลับไม่ได้ถูกลบบรรทัด

<U002E> IGNORE;IGNORE;IGNORE;<U002E> # 47 .

แต่แทนที่จะปรับเปลี่ยนเป็น

<U002E> <RES-1>;IGNORE;IGNORE;<U002E> # 47 .

ทำไมถึงใช้งานได้

IGNOREงบระบุว่าหยุดเต็ม (ระยะเวลาที่รู้จักกันในชื่อหรือตัวอักษร<U002E>) จะถูกละเว้นเมื่อคำสั่งซื้อตามลำดับตัวอักษร ในการทำให้ dotfiles ของคุณเป็นอันดับแรกให้เปลี่ยนIGNOREเป็นสัญลักษณ์การเรียงที่มาก่อนอักขระอื่นทั้งหมด สัญลักษณ์การเรียงจะถูกกำหนดโดยบรรทัดเช่น

collating-symbol <something-inside-angle-brackets>

และพวกเขาจะได้รับคำสั่งจากการปรากฏตัวของเส้น

<something-inside-angle-brackets>

ในสำเนาของฉัน iso14651_t1_commonสัญลักษณ์การเรียงลำดับแรกคือ<RES-1>ซึ่งจะปรากฏที่บรรทัด 3458 หากไฟล์ของคุณแตกต่างกันให้ใช้สัญลักษณ์การเรียงที่ใดก็ได้ก่อน

รายละเอียดเกี่ยวกับการสั่งซื้อตัวอักษรด้วย LC_COLLATE

<U002E>มีสามIGNOREข้อความเพราะตัวอักษรสามารถเปรียบเทียบได้หลายครั้งในกรณีที่มีความสัมพันธ์กัน เพื่อให้เข้าใจสิ่งนี้ให้พิจารณาตัวพิมพ์เล็กaและตัวพิมพ์ใหญ่A(ซึ่งเป็นส่วนหนึ่งของกลุ่มอักขระที่ได้รับการเปรียบเทียบจริงสี่ครั้ง):

<U0061> <a>;<BAS>;<MIN>;IGNORE # 198 a
<U0041> <a>;<BAS>;<CAP>;IGNORE # 517 A

การมีการเปรียบเทียบหลายรอบอนุญาตให้ไฟล์ที่ขึ้นต้นด้วย "a" และ "A" ถูกจัดกลุ่มเข้าด้วยกันเพราะทั้งคู่จะถูกเปรียบเทียบ<a>ในระหว่างการส่งครั้งแรกด้วยตัวอักษรถัดไปเพื่อกำหนดลำดับ หากตัวอักษรทั้งหมดต่อไปนี้เหมือนกัน (เช่นa.txtและA.txt) รหัสผ่านตัวที่สามจะใส่a.txtก่อนเพราะสัญลักษณ์การเรียงตัวอักษรตัวพิมพ์เล็ก<MIN>จะปรากฏที่บรรทัดที่ 3467 ก่อนที่สัญลักษณ์การเรียงตัวอักษรตัวพิมพ์ใหญ่<CAP>(บรรทัด 3488)

ใช้การเปลี่ยนแปลงนี้

หากคุณต้องการให้ช่วงเวลานั้นมาก่อนทุกครั้งที่โปรแกรมสั่งให้ใช้ตัวอักษรLC_COLLATEคุณสามารถแก้ไขiso14651_t1_commonตามที่อธิบายไว้ข้างต้นและสร้างไฟล์ตำแหน่งของคุณใหม่ แต่ถ้าคุณต้องการที่จะทำให้การเปลี่ยนแปลงนี้เท่านั้นที่จะlsและไม่สามารถเข้าถึงรากคุณสามารถคัดลอกไฟล์สถานที่เดิมไปยังไดเรกทอรีอื่นก่อนที่จะปรับเปลี่ยนพวกเขา

ฉันทำอะไรไป

ตำแหน่งที่ตั้งเริ่มต้นของฉันคือ en_US ดังนั้นผมคัดลอกen_US, iso14651_t1และการiso14651_t1_common $HOME/path/to/new/localesมีฉันทำการเปลี่ยนแปลงดังกล่าวจะiso14651_t1_commonเปลี่ยนไปen_US en_DOTFILEต่อไปฉันรวบรวมภาษา en_DOTFILE ด้วย

localedef -i en_DOTFILE -f UTF-8 -vc $HOME/path/to/new/locales/en_DOTFILE.UTF-8

หากต้องการแทนที่การlsสั่งซื้อเริ่มต้นให้สร้างสคริปต์ BASH ชื่อls:

#!/bin/bash
LOCPATH=$HOME/path/to/new/locales LANG=en_DOTFILE.UTF-8 ls "$@"

บันทึกไว้ที่ใดที่หนึ่งที่ปรากฏขึ้นก่อนในเส้นทางของคุณและทำให้มันปฏิบัติการด้วย/usr/binchmod +x ls


แน่นอนว่าคุณจะต้องเพิ่ม -a หรือ -A เพื่อดู dotfiles ของคุณ แต่ถ้าคุณไม่ต้องการเห็นมันตลอดเวลามันสมเหตุสมผลที่จะทำเช่นนั้นในบรรทัดคำสั่งไม่ใช่สคริปต์ BASH ของคุณ
beandip

ยอดเยี่ยม! ขอบคุณมันสมบูรณ์แบบ! ฉันเพิ่งแก้ไขไฟล์ที่เป็นเจ้าของรูทดังนั้นฉันจึงไม่ได้ทดสอบสคริปต์ของคุณ $@แต่ผมคิดว่าคุณจะต้องใส่คำพูดสองรอบของคุณ
Sparhawk

การโทรที่ดี - เพิ่มเครื่องหมายคำพูดคู่แล้ว
beandip

11

คุณสามารถใช้การเรียงลำดับของเปลือกแทน (ซึ่งอาจจะไม่เกี่ยวข้องกับการสั่งซื้อการเปรียบเทียบที่เกิดเหตุของ; bash, AT & T ksh, yash, tcshและzshให้ผลที่คาดหวัง, mkshและdash. ไม่fishน่าจะให้กรณีคำสั่งตาย แต่ให้ผลลัพธ์ที่แตกต่างเมื่อมีไม่ใช่ ASCII ตัวอักษร):

ls -dUl -- .* *

สิ่งนี้ให้lsรายการไฟล์ (และไดเรกทอรี) อย่างชัดเจนเพื่อแสดงรายการและยกเลิกlsการเรียงลำดับของ ( -Uซึ่งเป็นส่วนขยายของ GNU)

มีคำเตือนอยู่บ้างเล็กน้อยขึ้นอยู่กับเปลือกหอยที่คุณใช้

  • ด้วยตัวเลือกzshเริ่มต้นnomatchจะทำให้คำสั่งล้มเหลวหากไดเรกทอรีไม่มีไฟล์ที่ซ่อนและไม่ได้ซ่อนอยู่; คุณสามารถปิดการใช้งานnomatchเพื่อหลีกเลี่ยงปัญหานั้นได้ แต่ควรทำเช่นนั้นset -o cshnullglobแทน (และคำสั่งจะล้มเหลวก็ต่อเมื่อไม่มี globs ที่ตรงกันเหมือนใน(t)cshหรือ Unix shell)
  • ด้วยzsh, pdkshและอนุพันธ์ของมันfish, และ.*การขยายตัวของมันไม่ได้รวม.และ..ดังนั้นการจับคู่ls -Alนี้ กับกระสุนอื่น ๆ.และ..รวมอยู่ด้วยดังนั้นมันจึงเข้าls -alกัน ในกรณีหลังคุณจะต้องเปลี่ยนรูปแบบการวนรอบเพื่อยกเว้น.และ..( ls -dUl -- ..?* .[!.]* *)
  • ยกเว้นในfish, (t)cshหรือzshถ้าใด ๆ ของรูปแบบ globbing ไม่ตรงกับสิ่งใดlsจะผลิตข้อความผิดพลาด; คุณสามารถหลีกเลี่ยงสิ่งนี้ได้โดยตั้งค่าnullglobตัวเลือก (ในbashหรือzshอย่างน้อย) หรือเปลี่ยนเส้นทางstderrไปที่/dev/null( ls -dUl -- ..?* .[!.]* * 2>/dev/null) ถ้าคุณใช้nullglobระวังพฤติกรรมที่อาจเกิดขึ้นน่าแปลกใจว่าสาเหตุ (ดูเชลล์กิน `?` ตัวอักษร ) fishพฤติกรรมเช่นbashมีnomatchยกเว้นว่าเมื่อโต้ตอบข้อความแจ้งเตือนจะมีการออกสำหรับแต่ละ glob ที่ไม่มีการแข่งขัน

(ขอบคุณStéphane Chazelasสำหรับคำติชมทั้งหมด!)


โปรดทราบว่าเชลล์บางตัวเท่านั้นที่จะเรียงลำดับรายการโดยใช้ลำดับการเรียงของโลแคล mkshและdashตัวอย่างเช่นจะไม่เรียงลำดับแบบตรงตามตัวพิมพ์ใหญ่ - เล็ก
Stéphane Chazelas

1
โปรดทราบว่า-U(หมายถึงไม่ได้เรียงลำดับ) เป็นส่วนขยายของ GNU lsการใช้งานอื่น ๆเช่น FreeBSD มี-Uแต่มันไม่ได้มีไว้สำหรับรายชื่อที่ไม่เรียงลำดับ
Stéphane Chazelas

ด้วย GNU lsคุณต้องใช้--มาก่อน.*เนื่องจากการใช้งานนั้นยอมรับตัวเลือกหลังการโต้แย้ง (เว้นแต่ POSIXLY_CORRECT อยู่ในสภาพแวดล้อม)
Stéphane Chazelas

ส่อเสียด (+1)! อย่างไรก็ตามฉันไม่แน่ใจว่าฉันจะใช้สิ่งนี้ได้อย่างไรในทุกกรณีเช่นในนามแฝงหรือฟังก์ชัน ตัวอย่างเช่นมันจะต้องเปลี่ยนถ้าฉันต้องการระบุไดเรกทอรีเฉพาะเพื่อlsเป็นอาร์กิวเมนต์
Sparhawk

1
@PeterCordes [!.]ถูกต้อง ดูpubs.opengroup.org/onlinepubs/9699919799/utilities/... เชลล์ (ส่วนใหญ่?) บางอันอนุญาตให้^ใช้เป็นคำพ้องความหมาย!ในคลาสอักขระที่ไม่ได้รับการตอบ ไม่ว่าในกรณีใดฉันชอบ.[!.] .??* *ที่จะเข้าใจมากกว่า.[!.]* ..?* *
jrw32982 รองรับ Monica

4

คุณอาจใช้สองlsคำสั่งแยกกัน:

$ ls -dl ..?* .[^.]* 2>/dev/null ; ls -dl *
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 .a
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 .b
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 a
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 A
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 b
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 B
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 你好嗎

ซึ่งแตกต่างจากคำตอบอื่น ๆ จนถึงวิธีการนี้จะแสดงไฟล์จุดก่อนหลีกเลี่ยง.และ..รายการจากนั้นรายการที่เหลือls ตามลำดับตัวอักษร

@StephenKitt คำตอบอาจได้รับการปรับปรุงเพื่อให้ได้ผลลัพธ์เดียวกัน:

$ ls -dUl ..?* .[^.]* * 2>/dev/null

+1 ด้วย แต่ตามคำตอบของ StephenKitt ฉันไม่แน่ใจว่าฉันจะใช้สิ่งนี้ได้อย่างง่ายดายในทุกกรณีเช่นในนามแฝงหรือฟังก์ชั่น ตัวอย่างเช่นมันจะต้องเปลี่ยนถ้าฉันต้องการระบุไดเรกทอรีเฉพาะเพื่อlsเป็นอาร์กิวเมนต์ (FWIW ฉันใช้ zsh แต่นี้จะเป็นประโยชน์สำหรับทุบตีคนผมคิดว่า.)
สปาร์

-2

คุณสามารถเล่นกับตัวเลือกคำสั่งls ลองสิ่งนี้:

# ls -laXr

ที่ไหน:

-l     use a long listing format
-a, --all
              do not ignore entries starting with .
-X     sort alphabetically by entry extension
-r, --reverse
              reverse order while sorting

ขออภัยดูเหมือนจะไม่ทำสิ่งที่ฉันต้องการ -Xประเภทธงโดยการขยายหลัง.ซึ่งจะแตกต่างกันโดยสิ้นเชิง นอกจากนี้ไฟล์ยังเรียงตามลำดับตัวอักษรย้อนกลับ นอกจากนี้ในขณะที่ dotfiles เป็นตัวอย่างของฉันมันจะไม่ทำงานในทุกกรณี (เช่นa.b c.d .a .c) นอกจากนี้คุณเคยใช้แทน-a -A
Sparhawk
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.