จะแสดงไฟล์ที่ซ่อนเฉพาะในเทอร์มินัลได้อย่างไร


154

ฉันมีไดเรกทอรีที่มีไฟล์หลายพันไฟล์บางไฟล์ถูกซ่อนอยู่

คำสั่งls -aแสดงรายการไฟล์ทั้งหมดรวมถึงไฟล์ที่ซ่อนอยู่ แต่ฉันต้องการเพียงเพื่อแสดงรายการไฟล์ที่ซ่อนอยู่

ฉันควรใช้คำสั่งอะไร


1
ง่าย ๆls -ld .*หรือls -ald .*จะทำงาน
John Strood

คำตอบ:


189

คำสั่ง:

ls -ld .?* 

จะแสดงรายการไฟล์ที่ซ่อนอยู่เท่านั้น

อธิบาย:

 -l     use a long listing format

 -d, --directory
              list  directory entries instead of contents, and do not derefer‐
              ence symbolic links

.?* will only state hidden files 

8
คุณไม่จำเป็นต้องมีเครื่องหมายคำถามสองข้อในนั้น * ครอบคลุม (เฉพาะตรงกับอักขระเดี่ยวใด ๆ * ตรงกับหมายเลขใด ๆ ของพวกเขา)
psusi

13
@psusi ผมคิดว่าเจตนาคือการยกเว้น.และ..จากการแข่งขัน แต่ก็ยังจะไม่รวม (ตามกฎหมายอย่างสมบูรณ์) ชื่อไฟล์ที่ซ่อนตัวเดียวเช่น.a, .1และอื่น ๆ บางทีลูกโลกที่ขยายได้ดีกว่านั้นก็อาจจะเป็น.!(|.)จุดตามตัวอักษรตามด้วยอะไรก็ได้ยกเว้นอะไรหรือจุดอื่น ๆ (เช่นเดียว)ls -d .!(|.)
steeldriver

@steeldriver เรียบร้อยการ ?? เวอร์ชันไม่รวม "." และ ".. " ดูเหมือนว่าจะเป็นผลมาจากการเล่นโวหารที่น่าสนใจ: ใช่หรือไม่? หรือ * จะตรงกับจุด แต่? ต้องตรงกับบางอย่างมิฉะนั้นชื่อจะถูกละเว้น
psusi

ในการระบุไดเรกทอรีและไฟล์ให้เพิ่มตัวเลือก F เช่น ls -ldF.? * ชื่อไดเรกทอรีมี "/" เนื่องจากไฟล์อักขระที่แสดงล่าสุดไม่มี
RCF

1
มันใช้งานได้ดียกเว้นมันยังมีรายการโฟลเดอร์ที่ซ่อนอยู่เช่น. vim ซึ่งฉันคิดว่าไม่ใช่ไฟล์ที่นี่ ฉันแก้ไขมันเหมือน ls -ldp.? * | grep -v / รายการนี้ซ่อนเฉพาะไฟล์ที่ไม่ได้ซ่อนโฟลเดอร์
Fred Yang

31
ls -d .!(|.)

ทำสิ่งที่ OP ต้องการหรือไม่


1
มันทำงานอย่างไร
SarcasticSully

รายการสิ่งที่ไดเรกทอรีด้วย และอย่าเขียนรายการอะไรเลยถ้าไม่มีใครแปลให้
patrick

1
ผมเข้าใจว่าใน!(pattern-list), pattern-listคือรายการหนึ่งหรือมากกว่าหนึ่งรูปแบบแยกจากกันโดยที่|แต่มันเป็นความสับสนสำหรับผมว่าคุณไม่ได้มีรูปแบบใด ๆ |ที่ด้านซ้ายของ คุณช่วยอธิบายไวยากรณ์ให้ฉันฟังได้ไหม
Carlos Mendoza

2
@CarlosMendoza ที่จะกลายเป็นรูปแบบที่ว่างเปล่าดังนั้นนี้เป็นเหมือน.ไม่ได้ตามมาด้วย (ไม่มีอะไรหรือ.) ไม่รวมตัวเองและ. ..
muru

16

หากคุณต้องการไฟล์ในไดเรกทอรีปัจจุบันของคุณ (ไม่มีการเรียกซ้ำ) คุณสามารถทำได้

echo .[^.]*

ซึ่งจะพิมพ์ชื่อของไฟล์ทั้งหมดที่ชื่อขึ้นต้นด้วย a .และตามด้วยอักขระที่ไม่ใช่จุดอย่างน้อยหนึ่งตัว โปรดทราบว่าสิ่งนี้จะล้มเหลวสำหรับไฟล์ที่ชื่อขึ้นต้นด้วยจุดต่อเนื่องดังนั้นตัวอย่าง....fooจะไม่แสดง

คุณสามารถใช้find:

find -mindepth 1 -prune -name '.*'

ความ-mindepthมั่นใจที่เราไม่ตรงกัน.และ-pruneวิธีการที่findจะไม่ลงไปในไดเรกทอรีย่อย



4

การใช้findและawk,

find . -type f | awk -F"/" '$NF ~ /^\..*$/ {print $NF}'

คำอธิบาย:

find . -type f -> แสดงรายการไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันพร้อมกับพา ธ ของมันเช่น

./foo.html
./bar.html
./.foo1

awk -F"/" '$NF ~ /^\..*$/ {print $NF}'

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


find -type fคุณก็สามารถใช้ -name "*"คุณไม่จำเป็นต้องอย่างชัดเจนกำหนดเส้นทางการค้นหาหรือ
terdon

3

find โดยปกติแล้วจะเป็นตัวเลือกที่ดีกว่าสำหรับการค้นหาที่ซับซ้อนกว่าการใช้ชื่อ globbing

find . -mindepth 1 -maxdepth 1 -name '.*'

หรือ

find . -mindepth 1 -maxdepth 1 -name '.*' -o -name '*~'

find . ค้นหาไดเรกทอรีปัจจุบัน

-mindepth 1ไม่รวม และ .. จากรายการ

-maxdepth 1 จำกัด การค้นหาไปยังไดเรกทอรีปัจจุบัน

-name '.*' ค้นหาชื่อไฟล์ที่ขึ้นต้นด้วยจุด

-o หรือ

-name '*~' ค้นหาชื่อไฟล์ที่ลงท้ายด้วยเครื่องหมายตัวหนอน (โดยปกติจะเป็นไฟล์สำรองจากโปรแกรมแก้ไขข้อความ)

อย่างไรก็ตามคำตอบนี้และคำตอบอื่น ๆ ทั้งหมดคือไฟล์ที่อยู่ใน.hiddenไฟล์ของไดเรกทอรีปัจจุบัน หากคุณกำลังเขียนสคริปต์บรรทัดเหล่านี้จะอ่าน.hiddenไฟล์และแสดงชื่อไฟล์ของไฟล์ที่มีอยู่

if [[ -f .hidden]] # if '.hidden' exists and is a file
then
    while read filename # read file name from line
    do
        if [[ -e "$filename" ]] # if the read file name exists
        then
            echo "$filename" # print it
        fi
    done < .hidden # read from .hidden file
fi

อะไรคือ.hiddenไฟล์? ทำไมถึงมีไฟล์ชื่อ.hiddenที่มีชื่อไฟล์อยู่ด้วย? อย่างไรก็ตามถ้ามีเหตุผลที่คุณจะทำบางสิ่งที่ซับซ้อนเมื่อทุกสิ่งที่คุณต้องการจะเป็นcat .hiddenอย่างไร findคำสั่งของคุณถูกต้อง (ish) แต่-name '*~'ไม่เกี่ยวข้อง ไฟล์ที่ลงท้ายด้วย tildes เป็นไฟล์สำรองข้อมูล แต่ไม่ถูกซ่อนไว้ แต่อย่างใด
terdon

@terdon .hiddenไฟล์สำหรับไฟล์และโฟลเดอร์ที่คุณต้องการซ่อนเมื่อคุณไม่สามารถเปลี่ยนชื่อไฟล์ / โฟลเดอร์เพื่อเริ่มต้นด้วยจุด สำหรับไฟล์ที่ลงท้ายด้วยตัวหนอนนั้นขึ้นอยู่กับระบบ ls -Bจะไม่สนใจไฟล์ดังกล่าวเช่นเดียวกับที่สำรวจไฟล์ GUI ส่วนใหญ่
Mark H

cat .hiddenอาจแสดงไฟล์ที่ไม่มีอยู่อีกต่อไปหากไฟล์เหล่านั้นถูกลบหรือย้ายตั้งแต่ถูกเพิ่มลงใน.hiddenไฟล์
Mark H

มันใช้งานได้ดี
Penghe Geng

2

ฉันคิดว่าคุณสามารถทำได้ด้วยคำสั่งดังต่อไปนี้

ls -a | grep "^\." | grep -v "^\.$" | grep -v "^\..$"

ls -a คำสั่งที่คุณป้อนซึ่งจะแสดงไฟล์และไดเรกทอรีทั้งหมดในไดเรกทอรีการทำงานปัจจุบัน

grep "^\."คำสั่งที่ฉันผนวกที่กรองเอาท์พุทเพื่อแสดงเฉพาะไฟล์ที่ซ่อนอยู่ (มันเป็นชื่อเริ่มต้นด้วย".")

grep -v "^\.$" | grep -v "^\..$" คำสั่งที่ฉันผนวกที่กรองเอาท์พุทเพื่อยกเว้น., .. (พวกเขาเป็นไดเรกทอรีปัจจุบันและผู้ปกครอง)

หากชื่อไฟล์บางไฟล์อาจมีมากกว่าหนึ่งบรรทัด"\n"ตัวอย่างข้างต้นอาจไม่ถูกต้อง

ดังนั้นฉันขอแนะนำคำสั่งต่อไปนี้เพื่อแก้ไขปัญหา

find -maxdepth 1 -name ".[!.]*"

6
คุณควรจะไม่เคยแยกการส่งออกของ ls
Radu Rădeanu

@ RaduRădeanuฉันเห็นความคิดเห็นของคุณมันดีมาก ฉันแก้ไขคำตอบของฉันอีกครั้ง ขอบคุณที่แสดงความคิดเห็น
xiaodongjie

2

คุณจะทำอะไรได้อีกis ls .?*หรือls .!(|)จะแสดงทุกอย่างในไฟล์ / ไฟล์ที่ซ่อนอยู่ด้านบนและไฟล์ / dirs ด้านล่าง

เช่นจากเทอร์มินัลของฉัน

$ ls .?*       
.bash_history    .dmrc        .macromedia   .weather
.bash_logout     .gksu.lock   .profile      .wgetrc
.bash_profile    .bashrc.save .ICEauthority .toprc           .Xauthority
.bashrc          .lastdir     .viminfo      .xsession-errors
.bashrc~         .dircolors   .lynxrc       .vimrc           .xsession-errors.old

..:
Baron

.adobe:
Flash_Player

.aptitude:
cache  config

.cache:
compizconfig-1                              rhythmbox
dconf                                       shotwell

ตอนนี้สังเกตเห็นในผลลัพธ์ข้างต้นมันจะแสดงให้คุณเห็นทุกไฟล์ / dir ด้วย subdir และไฟล์ที่ซ่อนอยู่ด้านล่าง

[1:0:248][ebaron@37signals:pts/4][~/Desktop]
$ ls .!(|)
.bash_aliases  .bashrc1  .bashrc1~

..:
askapache-bash-profile.txt  examples.desktop             Public           top-1m.csv
backups             Firefox_wallpaper.png        PycharmProjects          top-1m.csv.zip
Desktop             java_error_in_PYCHARM_17581.log  Shotwell Import Log.txt  topsites.txt
Documents           Music                Templates            Videos
Downloads           Pictures                 texput.log           vmware

ขออภัยฉันไม่สามารถแสดงความคิดเห็น ที่จะอธิบายความแตกต่างระหว่างที่นี่ls .?*และ @ คำตอบ cioby23 ls -d .[!.]* .??*และทำไมมันเป็นจริงการพิมพ์ไฟล์ที่ซ่อนอยู่สองครั้งเป็นเพราะตัวอักษรที่คุณถามสองครั้ง.??*, .?*, .[!.]*พวกเขากำลังสิ่งเดียวกันเพื่อเพิ่มใด ๆ ของพวกเขาด้วยตัวอักษรคำสั่งที่แตกต่างกันจะพิมพ์เป็นครั้งที่สอง


1

คุณยังสามารถใช้:

ls -d .[!.]* .??*

สิ่งนี้จะช่วยให้คุณแสดงไฟล์ที่ซ่อนอยู่ปกติและไฟล์ที่ซ่อนซึ่งเริ่มต้นด้วย 2 หรือ 3 จุดเช่น: ..hidden_file


1
ด้วยวิธีนี้ฉันได้รับไฟล์ที่ซ่อนอยู่สองครั้ง
TuKsn

1

คุณสามารถใช้คำสั่ง

ls -Ad .??*

นี่เป็นข้อได้เปรียบของการอนุญาตให้มีการแสดงรายการหลายคอลัมน์ซึ่งแตกต่างจากวิธีการ grep-based ในls -a | grep "^\."โซลูชัน


1

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

คำสั่งเต็มคือ:

ls -d $(echo -e "$(\ls)\n$(\ls -A)" | sort | uniq -u)

คำอธิบาย

สิ่งนี้ทำคือรายการไฟล์ทั้งหมด (และไดเรกทอรี) สองครั้ง

echo -e "$(\ls)\n$(\ls -A)"

-Aแต่การแสดงไฟล์ที่ซ่อนอยู่ครั้งหนึ่ง

จากนั้นรายการจะถูกจัดเรียง| sortซึ่งทำให้ไฟล์ (ไม่ถูกซ่อน) ปกติปรากฏขึ้นสองครั้งและอยู่ติดกัน

จากนั้นให้ลบทุกบรรทัดที่ปรากฏมากกว่าหนึ่งครั้ง| uniq -uออกจากบรรทัดที่ไม่ซ้ำกันเท่านั้น

สุดท้ายใช้อีกครั้งเพื่อแสดงรายการไฟล์ทั้งหมดที่มีตัวเลือกที่กำหนดเองของผู้ใช้และไม่มีรายชื่อเนื้อหาของไดเรกทอรีในรายการls-d

แก้ไข (ข้อ จำกัด ):

วิธีแก้ปัญหานี้จะไม่ทำงานอย่างถูกต้องหากมีไฟล์ที่มีชื่อเช่นescaped\ncharacter.txtเพราะecho -eจะแยกชื่อไฟล์ออกเป็นสองบรรทัด มันจะไม่ทำงานอย่างที่คาดไว้หากมีไฟล์ที่ซ่อนอยู่สองไฟล์ที่มีชื่อเดียวกันเกือบทั้งหมดยกเว้นอักขระพิเศษเช่น.foo[tab].txtและ.foo[new-line].txtเนื่องจากทั้งสองไฟล์ถูกพิมพ์เป็น.foo?.txtและจะถูกกำจัดโดยuniq -u


1
ฉันคิดว่านั่นเป็นคำจำกัดความของไฟล์ที่ซ่อนอยู่ แม้แต่ที่มาของไฟล์ที่ซ่อนอยู่ก็มาจากข้อบกพร่องในการจัดการกับ.ตัวละครตัวแรก
muru

ฉันพูดถึงว่า (ตามความเป็นจริง) ในวรรคแรก อย่างไรก็ตามยังคงได้รับผลลัพธ์ที่แตกต่างจากคำตอบที่ยอมรับในปัจจุบัน
alejandro

แน่นอนว่ามันไม่รวม..แต่ฉันสงสัยว่ามันทำงานได้ดีกับชื่อไฟล์ที่มีอักขระพิเศษอย่างไร
muru

ฉันไม่ทราบว่าคุณหมายถึงอะไรโดยตัวละครพิเศษ แต่ฉันคิดว่ามันจะไม่เกิดปัญหาเพราะวิธีนี้ไม่ได้คิดอะไรเกี่ยวกับชื่อไฟล์
alejandro

ที่จริงแล้วคุณถือว่าอย่างน้อยหนึ่งอย่าง: ชื่อไฟล์จะไม่มีบรรทัดใหม่ในนั้น เช่นกัน: ชื่อไฟล์ไม่มีลำดับการหลบหลีกในสิ่งที่echo -eจะตีความ นอกจากนี้: lsจะไม่ทำให้ชื่อไฟล์ยุ่งเหยิงเพื่อให้ชื่อไฟล์ที่แตกต่างกันสองตัวปรากฏขึ้นเหมือนกัน (ตัวอย่างเช่นในบางเวอร์ชันlsจะใช้?สำหรับอักขระพิเศษดังนั้น.foo\tbar( \t= แท็บ) และ.foo\nbar( \n=> ขึ้นบรรทัดใหม่) จะปรากฏขึ้นเป็นทั้งคู่foo?bar)
muru

1

หรือคุณสามารถใช้ echo .*

เช่น

user@linux:~$ echo .*
. .. .bash_aliases .bash_history .bash_logout .bashrc
user@linux:~$

หากคุณต้องการในรูปแบบรายการแบบยาวให้แปลงพื้นที่สีขาวเป็นบรรทัดใหม่

user@linux:~$ echo .* | tr ' ' '\n'
.
..
.bash_aliases
.bash_history
.bash_logout
.bashrc
user@linux:~$ 

0

ด้วย bash การตั้งค่าGLOBIGNOREตัวแปรพิเศษคือค่าที่ไม่ว่างเปล่าเพียงพอที่จะทำให้มันไม่สนใจ.และ..เมื่อขยาย globs จากBash docs :

GLOBIGNOREตัวแปรเปลือกอาจจะถูกใช้เพื่อ จำกัด ชุดของชื่อไฟล์ตรงกับรูปแบบที่ หากGLOBIGNOREมีการตั้งค่าชื่อไฟล์ที่ตรงกันแต่ละรายการที่ตรงกับหนึ่งในรูปแบบในGLOBIGNOREจะถูกลบออกจากรายการที่ตรงกัน หากnocaseglobมีการตั้งค่าตัวเลือกการจับคู่กับรูปแบบในGLOBIGNOREจะดำเนินการโดยไม่คำนึงถึงกรณี ชื่อไฟล์.และ..จะถูกละเว้นเสมอเมื่อ GLOBIGNOREตั้งค่าและไม่ว่าง อย่างไรก็ตามการตั้งค่าเป็นค่าGLOBIGNOREที่ไม่ใช่ศูนย์จะมีผลในการเปิดใช้งานตัวเลือกเปลือก dotglob ดังนั้นชื่อไฟล์อื่น ๆ ทั้งหมดที่ขึ้นต้นด้วย‘.'จะตรงกัน

หากเราตั้งค่าเป็น.:..ทั้ง.และ..จะถูกละเว้น เนื่องจากการตั้งค่าเป็นอะไรที่ไม่เป็นโมฆะจะทำให้เกิดพฤติกรรมเช่นนี้เราจึงอาจตั้งค่าเป็น.

ดังนั้น:

GLOBIGNORE=.
ls -d .*
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.