แสดงรายการไฟล์ปกติเท่านั้น (แต่ไม่ใช่ไดเรกทอรี) ในไดเรกทอรีปัจจุบัน


126

ฉันสามารถใช้ls -ld */เพื่อแสดงรายการไดเรกทอรีทั้งหมดในไดเรกทอรีปัจจุบัน มีวิธีที่ง่ายเหมือนกันเพียงแค่แสดงรายการไฟล์ปกติทั้งหมดในไดเรกทอรีปัจจุบันหรือไม่? ฉันรู้ว่าฉันสามารถใช้การค้นหา

find . -maxdepth 1 -type f

หรือสถิติ

stat -c "%F %n" * | grep "regular file" | cut -d' ' -f 3-

แต่สิ่งเหล่านี้ไม่ได้ทำให้ฉันรู้สึกว่าสง่างามเกินไป มีวิธีสั้น ๆ ที่ดีในการแสดงเฉพาะไฟล์ปกติ (ฉันไม่สนใจเกี่ยวกับอุปกรณ์ท่อ ฯลฯ ) แต่ไม่ใช่ไดเรกทอรีย่อยของไดเรกทอรีปัจจุบันหรือไม่? รายชื่อลิงก์สัญลักษณ์เช่นกันจะเป็นข้อดี แต่ก็ไม่จำเป็น


5
คุณหมายถึงอะไร "ฉลาดเกินควร"? เท่าที่ฉันรู้findคำสั่งเป็นวิธีที่ดีที่สุดในการทำสิ่งที่คุณต้องการ สำหรับตัวเลือกอื่น ๆ ที่เชื่อถือได้คุณควรตรวจสอบคำสั่งเฉพาะของเชลล์
rahmu

@rahmu ฉันมีบางอย่างที่คล้ายกันls -d */ซึ่งสั้นง่ายต่อการพิมพ์และเข้าใจง่าย ดังนั้นฉันค่อนข้างมีความสุขกับคำตอบของ Ulrich Dangel แม้ว่าฉันไม่ได้ใช้ zsh
daniel kullmann

คำตอบ:


32

ด้วยzshและGlob Qualifiersคุณสามารถแสดงได้โดยตรงเช่น:

echo *(.)

จะส่งคืนรายการไฟล์ปกติเท่านั้นหรือมีข้อผิดพลาดขึ้นอยู่กับการกำหนดค่าของคุณ

สำหรับที่ไม่ใช่ไดเรกทอรี:

echo *(^/)

(จะรวม symlink (รวมถึงไดเรกทอรี), ชื่อไปป์, อุปกรณ์, ซ็อกเก็ต, ประตู ... )

echo *(-.)

สำหรับไฟล์ปกติและ symlink ไปยังไฟล์ปกติ

echo *(-^/)

สำหรับที่ไม่ใช่ไดเรกทอรีและไม่มีการเชื่อมโยงไปยังไดเรกทอรีทั้ง

นอกจากนี้ให้ดูที่Dรอบคัดเลือก globbing ถ้าคุณต้องการที่จะรวมDไฟล์ OT (ไฟล์ที่ซ่อนอยู่) *(D-.)เช่น


170
ls -p | grep -v / 

คำสั่งนี้แสดงรายการไฟล์ที่ไม่ได้ซ่อนไว้ทั้งหมดที่ไม่ใช่ไดเรกทอรี (ไฟล์ปกติลิงก์ไฟล์อุปกรณ์ฯลฯ ) หากต้องการรวมไฟล์ที่ซ่อนอยู่ให้เพิ่ม-Aตัวเลือกในls

มันถือว่าไม่มีไฟล์ใดมีตัวอักษรขึ้นบรรทัดใหม่ในชื่อของพวกเขา การเพิ่ม-qตัวเลือกในการlsแปลงอักขระที่ไม่สามารถพิมพ์ได้ทั้งหมดรวมถึงการขึ้นบรรทัดใหม่เป็นการ?รับประกันว่าพวกเขาอยู่ในบรรทัดเดียวและเหมาะสำหรับป้อนไปยังโปรแกรมอรรถประโยชน์ที่ใช้บรรทัดเช่นgrepและสำหรับการพิมพ์บนเทอร์มินัล


14
+1 นี่คือคำตอบที่ดี การลงคะแนนเสียงของผู้ใช้รายใหม่ที่ไม่มีความคิดเห็นนั้นค่อนข้างน่าตกใจสำหรับฉันโดยเฉพาะเมื่อมีคำตอบที่ใช้งานได้ กรณีขอบเดียวที่ฉันสามารถดูที่นี้จะไม่ทำงานอย่างถูกต้องคือถ้ามีการขึ้นบรรทัดใหม่ในชื่อไฟล์ การยึดสีไว้ด้วยจะเป็นส่วนเสริมที่ดี สำหรับ GNU คุณสามารถเพิ่ม--color=alwaysไปlsสำหรับ -GOSX
แกรม

สวัสดีคำสั่งที่คุณให้มานั้นยอดเยี่ยมมากและมันช่วยฉันออกมาได้อย่างแน่นอน แต่ฉันก็สงสัยว่ามันเป็นไปได้ไหมที่จะใช้คำสั่งด้านบนและเปลี่ยนการอนุญาตของไฟล์ในเวลาเดียวกัน? ฉันพยายามเพิ่มในsudo chmod 777ตอนท้ายและฉันได้รับข้อผิดพลาด ... ความช่วยเหลือใด ๆ ที่ชื่นชมอย่างมาก
dissidia

3
หากคุณยังต้องการที่จะยกเว้น symlinks ls -pL | grep -v /ที่ชี้ไปยังไดเรกทอรีทำ -Lลิงก์สัญลักษณ์ที่เพิ่มเข้ามา
Matthias Braun

1
ls -pdL something* | grep -v /หากคุณยังต้องการที่จะใช้ตัวกรองตัวแทนทำ -dตัวเลือกที่เพิ่มเข้ามาจะแสดงรายการไดเรกทอรีเองไม่ใช่เนื้อหาดังนั้นจึงจะถูกแยกออกอย่างถูกต้อง
Rockallite

และถ้าคุณต้องการคว้าไฟล์ทั้งหมดโดยไม่มีโฟลเดอร์ให้ลบ the -v
jasonleonhard

23

ในการแสดงรายการไฟล์ปกติเท่านั้น:

ls -al | grep '^-'

ด้วยลิงก์สัญลักษณ์ (ไปยังไฟล์ประเภทใด ๆ ) รวม:

ls -al | grep '^[-l]'

ในกรณีที่ตัวอักษรตัวแรกของรายการอธิบายชนิดของไฟล์ดังนั้นหมายความว่ามันเป็นแฟ้มปกติสำหรับการเชื่อมโยงสัญลักษณ์คือ-l

Debian / Ubuntu

พิมพ์ชื่อของไฟล์ที่ตรงกันทั้งหมด (รวมถึงลิงค์):

run-parts --list --regex . .

ด้วยเส้นทางที่แน่นอน:

run-parts --list --regex . "$PWD"

พิมพ์ชื่อของไฟล์ทั้งหมด/etcที่ขึ้นต้นด้วยpและลงท้ายด้วยd:

run-parts --list --regex '^p.*d$' /etc

15

lsไม่มีตัวเลือกในการทำเช่นนั้น แต่หนึ่งในสิ่งที่ดีเกี่ยวกับยูนิกซ์ & ลินุกซ์คือท่อที่ยืดยาวและไม่เหมาะสามารถเปลี่ยนเป็นสคริปต์เชลล์ฟังก์ชั่นหรือนามแฝงได้อย่างง่ายดาย และในทางกลับกันก็สามารถใช้ในท่อเหมือนโปรแกรมอื่น ๆ

(หมายเหตุ: มีปัญหาบางอย่างเกี่ยวกับฟังก์ชั่นและนามแฝงสคริปต์สามารถใช้งานได้สำหรับการปฏิบัติการที่สามารถอ่านและดำเนินการได้นามแฝงและฟังก์ชั่นนั้นมีให้ใช้งานในเชลล์ปัจจุบันเท่านั้น - แม้ว่าไฟล์ย่อย. profile / .bashrc และทำให้พร้อมใช้งานนอกจากนี้สคริปต์สามารถเขียนในภาษาใดก็ได้ - รวมถึง bash / sh, awk, perl, python และอื่น ๆ - ไม่ว่าอย่างใดอย่างหนึ่งที่ดีที่สุดสำหรับงานหรือที่คุณคุ้นเคยมากที่สุด)

เช่น

alias lsf='find . -maxdepth 1 -type f -print0 | xargs -0r ls'

ฉันได้เพิ่ม xargs เพื่อให้คุณสามารถใช้lsตัวเลือกปกติทั้งหมดเช่นlsf -lrS

เนื่องจากมันใช้finddotfiles ที่ซ่อนอยู่ตามปกติทั้งหมดจะปรากฏขึ้นและชื่อไฟล์ทั้งหมดจะถูกนำหน้าด้วย. / - นั่นคือความแตกต่างเพียงอย่างเดียวที่คุณจะสังเกตเห็น

คุณสามารถยกเว้นไฟล์ดอทได้! -iname '.*'แต่คุณต้องมีนามแฝงสองเวอร์ชัน - หนึ่งไฟล์ซึ่งแสดงไฟล์ดอทและอีกไฟล์ที่ไม่มี

alias lsf2='find . -maxdepth 1 -type f -a ! -iname '\''.*'\'' -print0 | xargs -0r ls'

หรือถ้าlsfเป็นสคริปต์มากกว่านามแฝงคุณสามารถแยกตัวเลือก (อาจจะมี getopts หรือ / usr / bin / getopt หรือคล้ายกัน) และยกเว้น dotfiles เว้นแต่-aเป็นปัจจุบัน


-name-inameก็พอคุณไม่จำเป็นต้อง
Totor

8
bash-4.2$ ls -F | grep -v '[/@=|]$' | more

อ็อพชัน -F เพื่อ ls ต่อท้าย * กับไฟล์เรียกทำงาน, / ไปยังไดเร็กทอรี, @ ไปยังลิงก์สัญลักษณ์, = ไปยังซ็อกเก็ตและ | ถึง FIFO จากนั้นคุณสามารถใช้ grep เพื่อแยกอักขระที่ไม่ใช่ไฟล์ปกติออกจากเอาต์พุตและคุณมีไฟล์ สิ่งนี้จะใช้ได้กับทุกเชลล์ไม่ใช่แค่ zsh

จุดอ่อนคือ:

  1. ไฟล์ใด ๆ ที่มีชื่อลงท้าย@ด้วย=หรือ|จะถูกแยกออก (แต่คุณไม่ควรมีไฟล์ที่มีอักขระเหล่านั้นในชื่อจริง ๆ )
  2. ไม่ได้ยกเว้นไฟล์อุปกรณ์หรือไฟล์ประเภทแปลกใหม่ในบางระบบเช่นประตู
  3. คุณจะต้องใส่เครื่องหมายดอกจันต่อท้ายไฟล์ใด ๆ ที่สามารถเรียกใช้งานได้ ที่สามารถจัดการได้โดยการไพพ์ผ่าน sed เพื่อลบอักขระ '*' ออกจากเอาต์พุต
  4. ไม่ทำงานอย่างถูกต้องหากมีชื่อไฟล์ที่มีอักขระขึ้นบรรทัดใหม่

ในระบบผมเขียนเกี่ยวกับเรื่องนี้ 10% ของไฟล์ที่มีชื่อที่มี=, @หรือ|ตัวอักษร =เป็นเรื่องปกติใน maildir หรือชื่อไฟล์ที่มีส่วนเข้ารหัส 64 หรือที่ยกมาได้ @ในคำจำกัดความของตำแหน่งที่ตั้งสำหรับที่อยู่อีเมลและอื่น ๆ มันหายากสำหรับพวกเขาที่จะปรากฏในตอนท้ายของชื่อไฟล์ว่า (เพียง 31 จาก 2.2 ล้านในระบบนี้เป็นต้น)
Stéphane Chazelas

3

คู่มือระบุตัวเลือก 'f' ผิดกับ 'ไฟล์ปกติ' เท่านั้นไม่ใช่ไปป์ซ็อกเก็ตหรืออุปกรณ์ป้องกัน / บล็อกซึ่งหมายความว่าคุณกำลังทำสิ่งที่ถูกต้องอยู่แล้ว

   -type c
          File is of type c:

          b      block (buffered) special

          c      character (unbuffered) special

          d      directory

          p      named pipe (FIFO)

          f      regular file

          l      symbolic link; this is never true if the -L option or the
                 -follow option is in effect, unless the symbolic link  is
                 broken.  If you want to search for symbolic links when -L
                 is in effect, use -xtype.

          s      socket

          D      door (Solaris)

0

นี่ไม่ใช่สั้นโดยเฉพาะ แต่คุณสามารถเปลี่ยนเป็นสคริปต์หรือนามแฝงหากคุณต้องการเรียกมันอย่างรวดเร็ว การใช้คำสั่ง ls เป็นอาร์เรย์อินพุตให้เรียก ls -ld บนแต่ละรายการที่ถูกไพพ์ไปยัง grep เพื่อแยกไดเรกทอรีที่มีเอาต์พุตที่ส่งเป็น null และหากประสบความสำเร็จจะสะท้อนอินพุตต้นฉบับ:

for list in `ls` ; do ls -ld $list | grep -v ^d > /dev/null && echo $list ; done ;

คุณสามารถสลับผลลัพธ์ grep และผลลัพธ์แบบมีเงื่อนไขผลลัพธ์แบบเดียวกัน:

for list in `ls` ; do ls -ld $list | grep ^d > /dev/null || echo $list ; done ;

\dev\null?!?!
จัดการ

ที่เกี่ยวข้อง: unix.stackexchange.com/questions/128985/why-not-parse-ls
Kusalananda

0

นี่เป็นเธรดเก่า แต่เป็นวิธีที่สะอาดที่สุดในการแสดงรายการไฟล์เท่านั้น

ls -al | grep '^-' | awk '{print $9}'

1
ที่เกี่ยวข้อง: unix.stackexchange.com/questions/128985/why-not-parse-ls
Kusalananda

1
touch "some file name"เพื่อดูตัวอย่างรวดเร็ว
Jeff Schaller

@JeffSchaller คุณมีจุดที่ถูกต้อง สำหรับบางอย่างเช่นนี้ ls -al | grep '^-' | awk '{ for(i=9; i<=NF; ++i) printf $i""FS; print "" }'ควรจัดการกับไฟล์ที่มีช่องว่างในพวกเขา
RJ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.