ฉันมีไดเรกทอรีที่มีไฟล์หลายพันไฟล์บางไฟล์ถูกซ่อนอยู่
คำสั่งls -a
แสดงรายการไฟล์ทั้งหมดรวมถึงไฟล์ที่ซ่อนอยู่ แต่ฉันต้องการเพียงเพื่อแสดงรายการไฟล์ที่ซ่อนอยู่
ฉันควรใช้คำสั่งอะไร
ฉันมีไดเรกทอรีที่มีไฟล์หลายพันไฟล์บางไฟล์ถูกซ่อนอยู่
คำสั่งls -a
แสดงรายการไฟล์ทั้งหมดรวมถึงไฟล์ที่ซ่อนอยู่ แต่ฉันต้องการเพียงเพื่อแสดงรายการไฟล์ที่ซ่อนอยู่
ฉันควรใช้คำสั่งอะไร
คำตอบ:
คำสั่ง:
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
.
และ..
จากการแข่งขัน แต่ก็ยังจะไม่รวม (ตามกฎหมายอย่างสมบูรณ์) ชื่อไฟล์ที่ซ่อนตัวเดียวเช่น.a
, .1
และอื่น ๆ บางทีลูกโลกที่ขยายได้ดีกว่านั้นก็อาจจะเป็น.!(|.)
จุดตามตัวอักษรตามด้วยอะไรก็ได้ยกเว้นอะไรหรือจุดอื่น ๆ (เช่นเดียว)ls -d .!(|.)
ls -d .!(|.)
ทำสิ่งที่ OP ต้องการหรือไม่
!(pattern-list)
, pattern-list
คือรายการหนึ่งหรือมากกว่าหนึ่งรูปแบบแยกจากกันโดยที่|
แต่มันเป็นความสับสนสำหรับผมว่าคุณไม่ได้มีรูปแบบใด ๆ |
ที่ด้านซ้ายของ คุณช่วยอธิบายไวยากรณ์ให้ฉันฟังได้ไหม
.
ไม่ได้ตามมาด้วย (ไม่มีอะไรหรือ.
) ไม่รวมตัวเองและ.
..
หากคุณต้องการไฟล์ในไดเรกทอรีปัจจุบันของคุณ (ไม่มีการเรียกซ้ำ) คุณสามารถทำได้
echo .[^.]*
ซึ่งจะพิมพ์ชื่อของไฟล์ทั้งหมดที่ชื่อขึ้นต้นด้วย a .
และตามด้วยอักขระที่ไม่ใช่จุดอย่างน้อยหนึ่งตัว โปรดทราบว่าสิ่งนี้จะล้มเหลวสำหรับไฟล์ที่ชื่อขึ้นต้นด้วยจุดต่อเนื่องดังนั้นตัวอย่าง....foo
จะไม่แสดง
คุณสามารถใช้find
:
find -mindepth 1 -prune -name '.*'
ความ-mindepth
มั่นใจที่เราไม่ตรงกัน.
และ-prune
วิธีการที่find
จะไม่ลงไปในไดเรกทอรีย่อย
การใช้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 "*"
คุณไม่จำเป็นต้องอย่างชัดเจนกำหนดเส้นทางการค้นหาหรือ
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 เป็นไฟล์สำรองข้อมูล แต่ไม่ถูกซ่อนไว้ แต่อย่างใด
.hidden
ไฟล์สำหรับไฟล์และโฟลเดอร์ที่คุณต้องการซ่อนเมื่อคุณไม่สามารถเปลี่ยนชื่อไฟล์ / โฟลเดอร์เพื่อเริ่มต้นด้วยจุด สำหรับไฟล์ที่ลงท้ายด้วยตัวหนอนนั้นขึ้นอยู่กับระบบ ls -B
จะไม่สนใจไฟล์ดังกล่าวเช่นเดียวกับที่สำรวจไฟล์ GUI ส่วนใหญ่
cat .hidden
อาจแสดงไฟล์ที่ไม่มีอยู่อีกต่อไปหากไฟล์เหล่านั้นถูกลบหรือย้ายตั้งแต่ถูกเพิ่มลงใน.hidden
ไฟล์
ฉันคิดว่าคุณสามารถทำได้ด้วยคำสั่งดังต่อไปนี้
ls -a | grep "^\." | grep -v "^\.$" | grep -v "^\..$"
ls -a
คำสั่งที่คุณป้อนซึ่งจะแสดงไฟล์และไดเรกทอรีทั้งหมดในไดเรกทอรีการทำงานปัจจุบัน
grep "^\."
คำสั่งที่ฉันผนวกที่กรองเอาท์พุทเพื่อแสดงเฉพาะไฟล์ที่ซ่อนอยู่ (มันเป็นชื่อเริ่มต้นด้วย"."
)
grep -v "^\.$" | grep -v "^\..$"
คำสั่งที่ฉันผนวกที่กรองเอาท์พุทเพื่อยกเว้น., .. (พวกเขาเป็นไดเรกทอรีปัจจุบันและผู้ปกครอง)
หากชื่อไฟล์บางไฟล์อาจมีมากกว่าหนึ่งบรรทัด"\n"
ตัวอย่างข้างต้นอาจไม่ถูกต้อง
ดังนั้นฉันขอแนะนำคำสั่งต่อไปนี้เพื่อแก้ไขปัญหา
find -maxdepth 1 -name ".[!.]*"
ls
คุณจะทำอะไรได้อีก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 .[!.]* .??*
และทำไมมันเป็นจริงการพิมพ์ไฟล์ที่ซ่อนอยู่สองครั้งเป็นเพราะตัวอักษรที่คุณถามสองครั้ง.??*
, .?*
, .[!.]*
พวกเขากำลังสิ่งเดียวกันเพื่อเพิ่มใด ๆ ของพวกเขาด้วยตัวอักษรคำสั่งที่แตกต่างกันจะพิมพ์เป็นครั้งที่สอง
คุณยังสามารถใช้:
ls -d .[!.]* .??*
สิ่งนี้จะช่วยให้คุณแสดงไฟล์ที่ซ่อนอยู่ปกติและไฟล์ที่ซ่อนซึ่งเริ่มต้นด้วย 2 หรือ 3 จุดเช่น: ..hidden_file
คุณสามารถใช้คำสั่ง
ls -Ad .??*
นี่เป็นข้อได้เปรียบของการอนุญาตให้มีการแสดงรายการหลายคอลัมน์ซึ่งแตกต่างจากวิธีการ grep-based ในls -a | grep "^\."
โซลูชัน
คำตอบทั้งหมดนั้นขึ้นอยู่กับข้อเท็จจริงที่ว่าไฟล์ (หรือไดเรกทอรี) ที่ชื่อขึ้นต้นด้วยจุดคือ "ซ่อน" ฉันใช้วิธีแก้ไขปัญหาอื่นซึ่งอาจไม่ได้ผล แต่โซลูชันนี้ไม่ได้คิดอะไรเกี่ยวกับชื่อของไฟล์ที่ซ่อนอยู่ดังนั้นจึงหลีกเลี่ยงการแสดงรายการ..
ในผลลัพธ์ (เช่นเดียวกับคำตอบที่ยอมรับในปัจจุบัน)
คำสั่งเต็มคือ:
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
.
ตัวละครตัวแรก
..
แต่ฉันสงสัยว่ามันทำงานได้ดีกับชื่อไฟล์ที่มีอักขระพิเศษอย่างไร
echo -e
จะตีความ นอกจากนี้: ls
จะไม่ทำให้ชื่อไฟล์ยุ่งเหยิงเพื่อให้ชื่อไฟล์ที่แตกต่างกันสองตัวปรากฏขึ้นเหมือนกัน (ตัวอย่างเช่นในบางเวอร์ชันls
จะใช้?
สำหรับอักขระพิเศษดังนั้น.foo\tbar
( \t
= แท็บ) และ.foo\nbar
( \n
=> ขึ้นบรรทัดใหม่) จะปรากฏขึ้นเป็นทั้งคู่foo?bar
)
หรือคุณสามารถใช้ 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:~$
ด้วย bash การตั้งค่าGLOBIGNORE
ตัวแปรพิเศษคือค่าที่ไม่ว่างเปล่าเพียงพอที่จะทำให้มันไม่สนใจ.
และ..
เมื่อขยาย globs จากBash docs :
GLOBIGNORE
ตัวแปรเปลือกอาจจะถูกใช้เพื่อ จำกัด ชุดของชื่อไฟล์ตรงกับรูปแบบที่ หากGLOBIGNORE
มีการตั้งค่าชื่อไฟล์ที่ตรงกันแต่ละรายการที่ตรงกับหนึ่งในรูปแบบในGLOBIGNORE
จะถูกลบออกจากรายการที่ตรงกัน หากnocaseglob
มีการตั้งค่าตัวเลือกการจับคู่กับรูปแบบในGLOBIGNORE
จะดำเนินการโดยไม่คำนึงถึงกรณี ชื่อไฟล์.
และ..
จะถูกละเว้นเสมอเมื่อGLOBIGNORE
ตั้งค่าและไม่ว่าง อย่างไรก็ตามการตั้งค่าเป็นค่าGLOBIGNORE
ที่ไม่ใช่ศูนย์จะมีผลในการเปิดใช้งานตัวเลือกเปลือก dotglob ดังนั้นชื่อไฟล์อื่น ๆ ทั้งหมดที่ขึ้นต้นด้วย‘.
'จะตรงกัน
หากเราตั้งค่าเป็น.:..
ทั้ง.
และ..
จะถูกละเว้น เนื่องจากการตั้งค่าเป็นอะไรที่ไม่เป็นโมฆะจะทำให้เกิดพฤติกรรมเช่นนี้เราจึงอาจตั้งค่าเป็น.
ดังนั้น:
GLOBIGNORE=.
ls -d .*
ls -ld .*
หรือls -ald .*
จะทำงาน