หลีกเลี่ยงรายการไฟล์ที่ลงท้ายด้วย ~ (ไฟล์สำรอง)


20

ความต้องการของฉันคือรายการไฟล์ทั้งหมดในไดเรกทอรียกเว้นไฟล์ที่ลงท้ายด้วย~(ไฟล์สำรอง)

ฉันพยายามใช้คำสั่ง:

ls -l | grep -v ~    

ฉันได้ผลลัพธ์นี้:

asdasad
asdasad~
file_names.txt
normaltest.txt
target_filename
testshell1.sh
testshell1.sh~
testshell2.sh
testshell2.sh~
testtwo.txt
testtwo.txt~
test.txt
test.txt~

ฉันต้องการรับเฉพาะไฟล์เหล่านี้:

asdasad
file_names.txt
normaltest.txt
target_filename
testshell1.sh
testshell2.sh
testtwo.txt
test.txt

~ดูเหมือนว่าคุณกำลังพยายามที่จะหลีกเลี่ยงการไฟล์รายชื่อที่ลงท้ายด้วย ไฟล์เหล่านี้เป็นไฟล์สำรองสร้างตัวแก้ไขข้อความของฉัน
ctrl-alt-delor

คุณใช้ระบบปฏิบัติการใด: เป็น Gnu / Linux (เช่น Debian, Ubuntu, Redhat, Centos, Fedora, Suse, Mint, Arch, ... )?
ctrl-alt-delor

2
โปรดทราบว่าไฟล์ที่คุณต้องการละเว้นดูเหมือนจะเป็นไฟล์สำรองของ Emacs มันค่อนข้างง่ายที่จะเปลี่ยนพฤติกรรมของ Emacs เพื่อที่จะได้ทำการบันทึกข้อมูลสำรองไว้ในไดเรกทอรีส่วนกลาง ดูemacs.stackexchange.com/questions/33/…
Kilian Foth

ฉันขอโทษที่ต้องใจร้าย แต่ฉันไม่เชื่อคุณ ls -l(ตัวอักษร ell) จะรวมถึงการอนุญาตลิงก์ย้อนกลับเจ้าของขนาดและ modtime สำหรับแต่ละไฟล์ที่ระบุไว้ สิ่งที่จะสร้างเอาต์พุตที่คุณแสดงคือls -1(หนึ่งหลัก) และในหลาย ๆ ระบบ-1จำเป็นต้องสร้างเอาต์พุตคอลัมน์เดียวบนเทอร์มินัลแต่เมื่อlsถูกไพพ์ (ตามที่นี่ไปgrep) หรือเปลี่ยนเส้นทาง-1ไม่จำเป็น .
dave_thompson_085

@ dave_thompson_085 ฉันตัดทอนข้อความทั้งหมดและมีเพียงชื่อไฟล์ที่นี่ .. เพราะฉันรู้สึกว่าไม่เกี่ยวข้อง และนี่คือระบบการผลิต (ไม่ใช่ระบบของฉันเอง) ดังนั้นฉันไม่ต้องการที่จะแสดงชื่อผู้ใช้รายละเอียดและรั่วไหลพวกเขา
curious_one

คำตอบ:


49
ls -l | grep -v ~

เหตุผลนี้ใช้ไม่ได้เนื่องจากตัวหนอนจะขยายไปยังโฮมไดเร็กตอรีของคุณดังนั้นgrepอย่าเห็นเครื่องหมายตัวหนอนที่แท้จริง (ดูตัวอย่างเช่นคู่มือของ Bash เกี่ยวกับ Tilde Expansion ) คุณจำเป็นต้องอ้างอิงเพื่อป้องกันการขยายตัวเช่น

ls -l | grep -v "~"

แน่นอนว่าสิ่งนี้จะยังคงลบบรรทัดเอาต์พุตใด ๆ ด้วยเครื่องหมายตัวหนอนที่ใดก็ได้แม้จะอยู่กลางชื่อไฟล์หรือที่อื่น ๆ ในlsผลลัพธ์ (แม้ว่าอาจไม่ปรากฏในชื่อผู้ใช้วันที่หรือชื่อ) หากคุณต้องการละเว้นไฟล์ที่ลงท้ายด้วยเครื่องหมายตัวหนอนเท่านั้นคุณสามารถใช้

ls -l | grep -v "~$"

48

การนำ GNU ไปใช้ls(พบในระบบ Linux ส่วนใหญ่) มีตัวเลือกดังนี้: -Bละเว้นการสำรองข้อมูล:

ls --ignore-backups

24

หากคุณกำลังใช้ bash ตรวจสอบให้แน่ใจว่าextglobเปิดใช้งานแล้ว:

shopt -s extglob

จากนั้นคุณสามารถใช้:

ls -d -- !(*~)
  • -d เพื่อไม่แสดงเนื้อหาของไดเรกทอรี
  • !(*~) ไฟล์ทั้งหมดยกเว้นไฟล์ที่ลงท้ายด้วย ~

บน zsh คุณสามารถทำเช่นเดียวกันกับkshglobตัวเลือกหรือใช้ globs ขยายของตัวเอง:

setopt extended_glob
ls -d -- ^*~

เนื่องจากส่วนต่อท้ายที่จะแยกออกมีความยาวเพียงหนึ่งตัวเท่านั้นคุณจึงสามารถจับคู่ชื่อไฟล์โดยที่อักขระตัวสุดท้ายไม่ใช่เครื่องหมายตัวหนอน (ซึ่งควรทำงานโดยไม่มีextglobเช่นกัน):

ls -d -- *[^~]

ls --ignore-backupsแต่ความคิดทั่วไปคือการใช้งาน


12

สิ่งนี้จะช่วย:

ls -l | grep -v '~'  

สาเหตุ: ~ char ถูกแทนที่โดยโฮมไดเร็กตอรี่ของคุณก่อนที่คำสั่งจะถูกดำเนินการ ลอง

echo ~

และ

echo '~'

6

ดังที่ได้กล่าวไว้ในคำตอบอื่น ๆ สาเหตุที่คุณน่าจะมีปัญหาก็คือเพราะคุณไม่ได้พูดหรือหลบเลี่ยงตัวหนอน

สำหรับกรณีการใช้งานหนึ่งโดยเฉพาะฉันได้ใช้การขยายชื่อไฟล์เชลล์เพื่อทำสิ่งที่คล้ายกัน ฉันใช้มันตั้งแต่ประมาณปี 2003 ซึ่งหมายความว่ามันทำงานกับการใช้งานเชลล์ที่หลากหลายในระบบที่แตกต่างกัน (ที่นี่ฉันยังใช้-Cเพราะฉันต้องการจอแสดงผลที่ดีในคอลัมน์เรียงลำดับ)

ls -C *[!~]

(ข้อ จำกัด ในการใช้การขยายชื่อไฟล์ของเชลล์แน่นอนว่าไดเรกทอรีที่มีไฟล์จำนวนมาก (ไม่ใช่ข้อมูลสำรอง) จะทำให้การขยายเกินขนาดรายการอาร์กิวเมนต์ที่มีอยู่แม้ว่าในระบบที่ทันสมัยส่วนใหญ่ข้อ จำกัด นี้ค่อนข้างสูงบ่อยครั้ง 250KB ขึ้นไปบางครั้งก็มากขึ้น)


1

ls | grep -v '~$'เป็นทางออกที่รวดเร็ว มันใช้ ls เพื่อแสดงรายการไฟล์ทั้งหมด (ไม่ซ่อน) จากนั้นใช้ grep กับ-v(จับคู่แบบกลับกันคือการแยก) เพื่อแยกบรรทัดทั้งหมดด้วยเครื่องหมายตัวหนอน ( ~) ที่ท้าย ($ )

อย่างไรก็ตามหากคุณมีไฟล์ใด ๆ ที่ชื่อว่า like1, something2 มันเป็นตัวบ่งชี้ที่ส่งกลิ่นมากว่าคุณมีเวิร์กโฟลว์ที่ไม่ดีซึ่งคุณควรแก้ไขที่แหล่งที่มา

หากคุณพบว่าตัวเองตั้งชื่อไฟล์ที่มีหมายเลขรุ่นเช่น test1 และ test2 หรือ testone และ testtwo สิ่งที่คุณต้องการคือระบบควบคุมเวอร์ชันเช่น gitแล้วสิ่งที่คุณต้องการจริงๆคือระบบการควบคุมเวอร์ชันเช่น

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

ระบบควบคุมเวอร์ชันช่วยให้คุณสามารถวางซ้อนหน้าต่างเวลาลงบนระบบไฟล์ดังนั้นคุณจะเห็นเพียงหน้าต่างเดียว testไฟล์แต่ภายใต้ประทุน (ผ่านโปรแกรมควบคุมเวอร์ชัน) ทุกเวอร์ชันพร้อมใช้งานเพื่อค้นหาเรียกคืนเปลี่ยนกลับเปรียบเทียบและอื่น ๆ .

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


1

แม้ว่าคำตอบจำนวนมากนั้นถูกต้อง (ฉันชอบคำที่@Foonเฉพาะเจาะจง) แต่ฉันก็ทราบว่าการรับรายชื่อด้วยls -lนั้นค่อนข้างอ่อนแอด้วยเหตุผลหลายประการ

เครื่องมือที่เหมาะสมในการค้นหาไฟล์คือแปลกใจ find .

หนึ่งในผลที่สุดของมันคือมันสามารถจัดการกับ "ตรรกะการเลือก" ด้วยตัวเองตัวอย่างเช่น:

$ find . -maxdepth 1 \( -type f -a \! -name '*~' \) -print

ซึ่งพูดfindกับ:

  1. ค้นหาไฟล์ในไดเรกทอรีปัจจุบัน: .
  2. มองหาพวกมันในระดับของไดเร็กตอรี่นั้น - นั่นคือ, อย่าทำการเรียกคืน: -maxdepth 1
  3. มองหาสิ่งที่อยู่ซึ่ง

    • ของไฟล์ประเภท: -type f
    • และ: -a
    • ชื่อที่ไม่สิ้นสุดใน~: ! -name *~ (โดยที่!negates คำสั่งต่อไปนี้ซึ่งตรงกับชื่อไฟล์-name *~)

    (ในการทำให้การจับคู่ทั้งประเภทและชื่อปรากฏเป็นหน่วยทางลอจิคัลมันจะใส่เครื่องหมายวงเล็บไว้กับ(และ))

  4. พิมพ์ชื่อของแต่ละไฟล์ที่พบ: -print.

คุณจำเป็นต้องปกป้องตัวละครบางตัวที่พิเศษให้กับเชลล์จากการตีความโดยเชลล์และนั่นคือสาเหตุที่วงเล็บและปัง!นั้นมีเครื่องหมายแบ็กสแลชและรูปแบบชื่อ*~ล้อมรอบด้วยเครื่องหมายคำพูดเดี่ยว

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

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