'ls -1': วิธีแสดงรายการชื่อไฟล์ที่ไม่มีส่วนขยาย


24

ls -1 แสดงรายการองค์ประกอบของฉันเช่น:

foo.png
bar.png
foobar.png
...

ฉันต้องการมันอยู่ในรายการโดยไม่.pngชอบ:

foo
bar
foobar
...

(dir มี.pngไฟล์เท่านั้น)

ใครสามารถบอกวิธีใช้grepในกรณีนี้ได้บ้าง

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


36
คุณต้องการระวังคำขอเช่นนี้ Linux ไม่มีส่วนขยายชื่อไฟล์ Linux มีชื่อไฟล์ที่อาจมีหรือไม่มี.อยู่ในนั้น แม้ว่าการประชุมกล่าวว่าการตั้งชื่อไฟล์ของคุณด้วย.pngในตอนท้ายมีเหตุผลว่าทำไมฉันไม่สามารถมี PNG ไฟล์ที่ชื่อว่าไม่มีfoo.zipหรือหรือเพียงแค่my.picture.20160518 mypic
Hymie

2
@hymie ฉันรู้ แต่องค์ประกอบของฉันในโฟลเดอร์นั้นตั้งชื่อทั้งหมดด้วย. png ในตอนท้าย
โคลิน

14
"ส่วนขยาย" คืออะไร นี่ไม่ใช่ส่วนหนึ่งของการตั้งชื่อไฟล์ Unix มันพกพาจาก VMS / NT / Windows ไม่ว่าอะไรก็ตาม และคุณเด็ก ๆ ก็ลงสนามหญ้าของฉันด้วย :)
mpez0

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

1
มันมักจะแนะนำให้หลีกเลี่ยงการแยกออกของlsและไปป์เอาท์พุทlsและfindส่วนใหญ่เป็นเพราะความเป็นไปได้ที่จะเกิดขึ้นในnewline`แท็บถ่านในชื่อไฟล์ หากชื่อไฟล์เป็นThe new art of working on .png\NEWLINE files and other formatsจำนวนมากวิธีการแก้ปัญหาที่เสนอจะสร้างปัญหา
Hastur

คำตอบ:


41

คุณต้องการเชลล์สำหรับงานนี้เท่านั้น

POSIXly:

for f in *.png; do
    printf '%s\n' "${f%.png}"
done

ด้วยzsh:

print -rl -- *.png(:r)

4
ไม่จำเป็นต้องมีสำหรับprintf; echo ${f%.png}จะพอเพียง
David Conrad

11
@Conrad: การใช้ echo จะไม่ทำงานอย่างถูกต้องในบางกรณีหากชื่อไฟล์เริ่มต้นด้วยเครื่องหมายขีดกลางหรือมีลำดับที่ใช้ Escape
cuonglm

3
@DavidConrad: โปรดดูunix.stackexchange.com/a/65819/38906
cuonglm

35
ls -1 | sed -e 's/\.png$//'

sedเอาคำสั่ง (นั่นคือจะแทนที่ด้วยสตริงว่างเปล่า) สตริงใด ๆ.pngพบได้ที่ส่วนท้ายของชื่อไฟล์

การ.หลบหนี\.เพื่อที่จะถูกตีความโดยsedเป็นตัว.อักษรมากกว่า regexp .(ซึ่งหมายถึงตรงกับตัวละครใด ๆ ) $เป็นสมอปลายของเส้นจึงไม่ตรงกับ.pngในช่วงกลางของชื่อไฟล์


4
ฉันคิดว่า OP ต้องการถอนส่วนขยายใด ๆแต่อาจเป็น "ส่วนสุดท้าย" เท่านั้น ดังนั้นอาจแก้ไขคำตอบที่ดีของคุณด้วย:sed 's/\.[^.]*$//'
Otheus

1
ใช่ว่า regexp จะทำงานในกรณีนั้น ... แต่ถ้า OP ต้องการสิ่งนั้นพวกเขาควรพูดอย่างนั้นแทนที่จะบอกว่าพวกเขา "ต้องการให้มันอยู่ในรายการโดยไม่มี. png"
cas

4
-1ไม่จำเป็นต้องเป็นค่าเริ่มต้นที่นี่
jlliagre

3
@jlliagre ฉันเห็นด้วยกับ cas ที่-1ควรระบุ เป็นเพียงค่าเริ่มต้นเมื่อเปิดใช้งาน pipe ซึ่งเป็นความประหลาดใจที่ซ่อนอยู่สำหรับบางคน ดังนั้นการทำให้ชัดเจนช่วยทำความเข้าใจ ฉันทำสิ่งนี้ในสคริปต์ของฉันด้วยดังนั้นฉันจึงรู้ว่าผลลัพธ์แบบไหนที่ฉันคาดหวัง
Otheus

1
คำเตือน ในกรณีของชื่อไฟล์ที่มีคีย์ ( .png) หน้าอักขระขึ้นบรรทัดใหม่คุณจะลบได้แม้ว่าจะ.pngไม่ใช่แค่ไฟล์สุดท้าย มันเป็นการดีกว่าที่จะหลีกเลี่ยงการไพพ์และแยกเอาท์พุทของ ls มันสงวนความประหลาดใจที่ซ่อนอยู่บ่อย ๆ ... (บางคำและการอ้างอิงเพิ่มเติมในคำตอบ)
Hastur

16

หากคุณต้องการใช้ bash:

for i in *; do echo "${i%.png}"; done

คุณควรไปถึงgrepเมื่อพยายามค้นหารายการที่ตรงกันไม่ใช่เพื่อลบ / ทดแทนสิ่งที่sedเหมาะสมกว่า:

find . -maxdepth 1 -name "*.png"  | sed 's/\.png$//'

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

find . -name "*.png"  | sed 's/\.png$//'

ls -1 | sed 's / .png //' ใช้งานได้ดี ขอขอบคุณ!
โคลิน

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

อาจแทนที่findด้วยสิ่งที่ชอบechoในตัวอย่างที่ผ่านมา ไม่ชัดเจนว่าจุดประสงค์การfindให้บริการที่นั่นและผลลัพธ์ขึ้นอยู่กับโครงสร้างไดเรกทอรี (เช่นถ้าคุณมีไดเรกทอรีfiles.png)

@BroSlow อัปเดตเป็นสิ่งที่สมเหตุสมผลมากขึ้น
Anthon

13

ฉันจะไปbasename(สมมติว่ามีการนำ GNU ไปใช้):

basename --suffix=.png -- *.png

โปรดทราบว่าหากคุณต้องการใช้ในไพพ์คุณอาจพบว่ามีประโยชน์ในการใช้ตัวเลือก-z(หรือ--zero) ของ GNU basename เพื่อสร้างเอาต์พุตที่คั่นด้วย NUL (แทนที่จะเป็นเอาต์พุตที่คั่นด้วยการขึ้นบรรทัดใหม่)
Toby Speight

11

อีกคำตอบที่คล้ายกันมาก (ฉันประหลาดใจที่ตัวแปรนี้ยังไม่ปรากฏ) คือ:

ls | sed -n 's/\.png$//p'
  • คุณไม่จำเป็นต้องใช้-1ตัวเลือกlsเนื่องจากlsถือว่าหากเอาต์พุตมาตรฐานไม่ใช่เทอร์มินัล (ในกรณีนี้เป็นไพพ์)
  • -nตัวเลือกที่จะsedหมายถึง 'ไม่ได้พิมพ์บรรทัดโดยค่าเริ่มต้น'
  • /pตัวเลือกในตอนท้ายของการเปลี่ยนตัวผู้เล่นหมายถึง ... และพิมพ์บรรทัดนี้ถ้าเปลี่ยนตัวได้ทำ '

ผลกระทบสุทธิของสิ่งนั้นคือการพิมพ์เฉพาะบรรทัดที่ลงท้าย.pngด้วยการ.pngลบออก นั่นคือสิ่งนี้ยังให้ความสำคัญกับการวางนัยทั่วไปของคำถามของ OP ที่ไดเรกทอรีไม่ได้มีเพียง.pngไฟล์

sed -nเทคนิคมักจะเป็นประโยชน์ในกรณีที่คุณมิฉะนั้นอาจใช้ grep + sed


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

2
@Hastur คุณถูกต้องตามหลักการและหน้าเว็บที่มีชื่อเสียงเกี่ยวกับการแยกวิเคราะห์ lsแสดงรายการปัญหาเพิ่มเติม (และวิธีแก้ปัญหา) เมื่อส่งชื่อไฟล์ทางพยาธิวิทยา แต่วิธีที่ดีที่สุดในการจัดการนั่นคือการหลีกเลี่ยงการมีชื่อไฟล์ทางพยาธิวิทยา (doh!); และถ้าคุณทำไม่ได้หรือถ้าคุณต้องแข็งแกร่งต่อพวกเขาให้ใช้findหรือ - อาจจะดีกว่า - ใช้ภาษาที่ทรงพลังมากกว่าshจัดการพวกเขา (ความจริงที่ว่าsh สามารถทำได้ทุกอย่างไม่ได้หมายความว่ามันเป็นตัวเลือกที่ดีที่สุดใน แต่ละกรณี). เชลล์ออกแบบมาเพื่อการใช้งานก่อน
นอร์แมนเกรย์

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

ยิ่งไปกว่านั้น IMHO มันเป็นเรื่องง่ายที่จะเริ่มต้นในการแยกวิเคราะห์lsแต่มันเป็นปัญหาในอนาคต บ่อยครั้งที่เราสร้างสคริปต์ที่เราจะใช้ในภายหลังเมื่อเราจะลืมข้อ จำกัด ของพวกเขา ... (เป็นมนุษย์มันเป็นเรื่องปกติ) ผมเสนอfindตัวอย่าง (ที่มี-execและไม่มีท่อ) แม้ว่าผมเห็นว่าดีกว่า (เพราะเปลือกบริสุทธิ์) ตอบหนึ่ง cuonglm ของของแข็งและตาม POSIX
Hastur

@Hastur: ปัญหาในอนาคตจะเกิดขึ้นต่อไป มีสิ่งต่าง ๆ มากมายในระบบที่ไม่แข็งแรงเมื่อเทียบกับไฟล์ที่มีบรรทัดใหม่ เช่นลองใช้locateหรือใช้makeกับพวกเขา
reinierpost

8

คุณสามารถใช้คำสั่ง BASH เท่านั้นที่จะทำเช่นนั้น (ไม่มีเครื่องมือภายนอก)

for file in *; do echo "${file%.*}"; done 

สิ่งนี้มีประโยชน์เมื่อคุณไม่มี / usr / bin และใช้งานได้ดีสำหรับชื่อไฟล์เช่น this.is.image.png และสำหรับส่วนขยายทั้งหมด


6

ไม่ปลอดภัยที่จะแยกวิเคราะห์lsหรือไปป์find[ 1 , 2 ]

มันไม่ปลอดภัยที่จะแยก (และท่อ) การส่งออกของlsหรือfindส่วนใหญ่เป็นเพราะมันเป็นไปได้ที่จะหาในชื่อไฟล์ตัวอักษรปกติไม่ใช่เป็นnewlineที่แท็บ ... ที่นี่รอบเปลือกบริสุทธิ์จะทำงาน[ cuonglm ]
แม้แต่findคำสั่งที่ไม่ได้ไพพ์ด้วยตัวเลือก-execก็สามารถใช้งานได้:

find ./*.png  -exec  basename {} .png  \;

อัปเดต / หมายเหตุ : คุณสามารถใช้find .เพื่อค้นหาแม้กระทั่งไฟล์ที่ซ่อนอยู่หรือfind ./*.pngเพื่อให้ได้เฉพาะไฟล์ที่ไม่ซ่อน ด้วยfind *.png -exec ...คุณสามารถมีปัญหาในกรณีที่มันเป็นไฟล์ชื่อ.pngเพราะหาจะได้รับมันเป็นตัวเลือก คุณสามารถเพิ่ม-maxdepth 0เพื่อหลีกเลี่ยงการสืบทอดในไดเรกทอรีที่ชื่อเป็นDir_01.pngหรือfind ./*.png -prune -exec ...เมื่อไม่อนุญาต maxdepth (ขอบคุณStéphane) หากคุณต้องการหลีกเลี่ยงการแสดงรายการไดเรกทอรีเหล่านั้นคุณควรเพิ่มตัวเลือก-type f(ซึ่งจะเป็นการยกเว้นไฟล์ที่ไม่ใช่ไฟล์ประเภทอื่นด้วย) ลองดูmanภาพพาโนรามาที่สมบูรณ์ยิ่งขึ้นเกี่ยวกับตัวเลือกทั้งหมดที่มีอยู่และอย่าลืมตรวจสอบว่าเป็นไปตาม POSIX เพื่อความสะดวกในการพกพามากขึ้น

บางคำเพิ่มเติม

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

The new art of working on .png
files and other formats.

หากคุณต้องการทดสอบคุณสามารถสร้างชื่อไฟล์แบบนี้ได้ด้วยคำสั่ง

touch "A file with two lines"$'\n'"and This is the second.png"
touch "The new art of working on .png"$'\n'"files and other formats.png"

วิ/bin/ls *pngออกจะง่าย ๆ?แทนที่จะเป็นอักขระที่ไม่สามารถพิมพ์ได้

A file with two lines?and This is the second.png
The new art of working on .png?files and other formats.png

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

รอบเปลือกหอยที่มีเปลือกพารามิเตอร์การขยายตัว${parameter%word}ทั้งในตัวแปรที่มีprintfหรือechoจะทำงาน[ cuonglm ], [ Anthon1 ]

for f in *.png; do printf "%s\n" "${f%.png}" ; done

จากหน้าแรกของการขยายพารามิเตอร์เชลล์[ 3 ]

$ {พารามิเตอร์% คำ}
$ {พารามิเตอร์ %% คำ}

... ผลลัพธ์ของการขยายคือค่าพารามิเตอร์ที่มีรูปแบบการจับคู่สั้นที่สุด (ตัวพิมพ์ '%') หรือรูปแบบการจับคู่ที่ยาวที่สุด (ตัวพิมพ์ '%%')


นอกจากนี้ผลลัพธ์ของfindคำสั่งของคุณจะเป็นตัวแปรบิต (ตัวอย่างเช่นหากมีไดเรกทอรีที่เรียกว่าfiles.png)

1
เรียน @BroSlow เมื่อฉันเขียนคำตอบข้างต้น ฉันลองใช้ 13 (ทั้งหมด) ของตัวแปรอื่นที่มีอยู่ในขณะนั้นโดยบรรทัดคำสั่งในสคริปต์ซึ่งเรียกใช้เป็นอาร์กิวเมนต์ของการเรียกใช้เชลล์ โปรดทำเช่นเดียวกันและบอกฉันว่าพวกเขาประพฤติในแบบที่คุณคาดหวัง ฉันทำการทดสอบด้วยbash 4.3.11ขีดกลาง 0.5.7-4, zsh (เมื่อจำเป็น) 5.0.2 รู้สึกอิสระที่จะอ่านโพสต์นี้ที่เพิ่มอะไรเพิ่มเติม ฉันเห็นด้วยเกี่ยวกับบันทึกย่อของการส่งออกท่อfindสำหรับเรื่องนี้ฉันแนะนำอย่างชัดเจน-execและฉันเขียนไว้ในชื่อเรื่อง :-).
Hastur

อ่าน wiki อีกครั้ง ฉันยังคงคิดว่าคุณต้องไปป์ไลน์ในตัวอย่างของคุณ และสำหรับเวอร์ชั่นที่ทันสมัยส่วนใหญ่lsนั้นจะไม่มีปัญหาใด ๆ เมื่อเอาต์พุตถูกไพพ์หรือเปลี่ยนทิศทาง แต่ตามที่กล่าวไว้ในวิกิมันอาจไม่ทำงานสำหรับทุกคน ส่วนใหญ่จะใส่?แทนที่อักขระพิเศษเมื่อส่งออกไปยังเทอร์มินัล คือ Do และecho *.png | od -c ls *.png | od -cปัญหาการขึ้นบรรทัดใหม่ไม่ใช่ปัญหากับlsมันเป็นปัญหากับคำสั่งใด ๆ ที่ไม่เป็นโมฆะยุติทั้งสองด้านของไปป์

1
printf "${f%.png}\n"มันผิด. อาร์กิวเมนต์แรกคือรูปแบบคุณไม่ควรใช้ข้อมูลตัวแปรในนั้น อาจเห็นว่าเป็นช่องโหว่ DoS (ลองกับ%1000000000s.pngไฟล์เป็นต้น)
Stéphane Chazelas

คุณต้องการfind ./*.png -prune -exec...หรือคุณมีปัญหาเกี่ยวกับชื่อไฟล์ที่ขึ้นต้นด้วย-(และไฟล์ประเภทได-maxdepth
เร็กตอรี่

4

มันไม่พอเหรอ?

ls -1 | sed 's/\.png//g'

หรือโดยทั่วไปสิ่งนี้

ls -1 | sed 's/\.[a-z]*//g'

จะลบส่วนขยายทั้งหมด


มันเป็น แต่โซลูชั่นอื่น ๆ ก็ทำงานเช่นกัน
โคลิน

ฉันหมายถึงว่าคำถามของคุณเริ่มต้นด้วย ls -1 ดังนั้น ls -1 ควรทำเช่นนั้น :)
Rohail Abbas

-1ไม่จำเป็นต้องเป็นค่าเริ่มต้นที่นี่
jlliagre

@Railail Abbas แต่ไม่ได้ติดตั้งทุกระบบใช่ไหม
โคลิน

1
แน่นอน แต่lsทำมันโดยไม่มีตัวเลือกนั้นเมื่อเอาท์พุทไม่ได้เป็นขั้วซึ่งเป็นกรณีที่นี่
jlliagre

3

ใช้rev:

ls -1 | rev | cut -f 2- -d "." | rev

revฝืนสตริงทั้งหมด (สาย); คุณตัดทุกอย่างหลังจากครั้งแรก '.' และ rev กลับรายการที่เหลืออีกครั้ง

หากคุณต้องการgrep'alma':

ls -1 | rev | cut -f 2- -d "." | rev | grep 'alma'

-1ไม่จำเป็นต้องเป็นค่าเริ่มต้นที่นี่
jlliagre

2
สิ่งนี้ล้มเหลวอย่างรุนแรงในไฟล์ชื่อMy.2016.Summer.Vacation.png
David Conrad

@DavidConrad ที่ไม่ดีของฉัน: / ฉันได้แก้ไขcut -f 2-
Tom Solid

ตอนนี้มันใช้งานได้กับไฟล์นั้น แต่ยังไม่พร้อมกับไฟล์ด้วย.pngและขึ้นบรรทัดใหม่หลังจาก ... ขอแนะนำให้หลีกเลี่ยงการแยกวิเคราะห์lsเพราะมันชอบที่จะซ่อนความประหลาดใจที่ดี ... :-)
Hastur

2

หากฉันรู้ว่าไดเรกทอรีนั้นมีไฟล์ที่มี. png เป็นส่วนขยายอยู่ฉันก็จะเรียกใช้: ls | awk -F. '{print $1}'

นี่จะส่งคืน "ฟิลด์" แรกสำหรับทุกสิ่งที่มีชื่อไฟล์

ตัวอย่าง:

[rsingh@rule51 TESTDIR]$ ls
10.png  1.png  2.png  3.png  4.png  5.png  6.png  7.png  8.png  9.png

[rsingh@rule51 TESTDIR]$ ls | awk -F. '{print $1}'
10
1
2
3
4
5
6
7
8
9

น่าเสียดายที่มันจะล้มเหลวในชื่อไฟล์ทั้งหมดที่มีมากกว่าหนึ่ง.ชื่อImage.1.pngและแม้แต่ในชื่อที่ไม่มีชื่อที่ดีและมีอักขระพิเศษอยู่ภายใน ขณะที่การขึ้นบรรทัดใหม่หรือคนที่คุณจะใช้เป็น (input) บันทึกคั่นใน,awk RSขอแนะนำให้หลีกเลี่ยงการแยกวิเคราะห์lsผลลัพธ์เพราะชอบซ่อนปัญหาที่จะเกิดขึ้นเมื่อคุณไม่คาดหวัง คุณสามารถอ่านเพิ่มเติมในการอ้างอิงเหล่านั้น1หรือ2 BTW ยินดีที่จะใช้ความคิด ... ฉันวางตัวอย่างไว้ในคำตอบเดียว
Hastur

จริง แต่ด้วยตัวอย่างที่ Colin จัดหาให้มันใช้ได้ดี หากต้องการให้ทำงานได้ตามที่คุณแนะนำฉันอาจเปลี่ยนเป็น: [rsingh @ rule51 TESTDIR] $ ls | sed -e 's / .png $ //' 10 1 2 3 4 5 6 7 8 9 harry.the.bunny whats.a.png.filename ไม่พยายามยาก แต่ได้รับความต้องการของโคลินฉันไม่แน่ใจ สิ่งที่ปัญหาจะแยกวิเคราะห์ ls
rsingh

ขอโทษ ... ฉันเพิ่งรู้ว่าฉันไม่ได้แสดงไดเรกทอรีด้วยไฟล์ก่อนที่จะแก้ไขการส่งออกของ 'ls' [rsingh @ rule51 TESTDIR] $ ls 10.png 2.png 4.png 6.png 8.png 8.png harry.the.bunny.png 1.png 3.png 5.png 7.png 9.png whats.a.png.filename.png [rsingh @ rule51 TESTDIR] $ ls | sed -e 's / .png $ //' 10 1 2 3 4 5 6 7 8 9 harry.the.bunny whats.a.png.filename
rsingh

Note1คุณต้องการที่จะหลบหนี.ใน\.ภายในsed -e 's/\.png$//'แต่มันจะกลายเป็นคำตอบเพียงแค่เขียน :-( note2คุณสามารถลองใช้awkกับสิ่งที่ชอบls | awk -F. '{if ($NF=="png") {for (i=1;i<NF-1;i++) printf("%s.", $i) ; printf $(NF-1)"\n"}}'... แต่คุณมักจะมีปัญหาที่ awk ไม่สามารถรู้ได้ว่าบรรทัดที่กำลังมาถึงกำลังติดตามหรือไม่ขึ้นบรรทัดใหม่ภายในชื่อไฟล์ฉันพยายามพูดได้ดีกว่าในคำตอบของฉัน .
Hastur

ขอบคุณ Hastur ฉันพลาดไป :) นอกจากนี้ฉันทิ้งการใช้ awk เพื่อ sed ในกรณีนี้
rsingh

2

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

for file in $(cat yourlist) ; do
  [ -f "${file}.png" ] || {
    echo "$file : listed in yourlist, but missing in the directory"
  }
done
#assumes that filenames have no space...
# otherwise use instead:
#  while IFS= read file ; do ...(same inner loop as above)... ; done < yourlist

และสิ่งที่ตรงกันข้าม:

for file in *.png ; do
  grep "^${file%.png}$" yourlist >/dev/null || {
    echo "$file: present in the directory but not listed in yourlist"
  }
done
#I assume there are no spaces/tabs/? before/after names in 'yourlist'. Change the script accordingly if there are some (or sanitize the list)

1

ls -l | sed 's/\.png$//'

เป็นวิธีที่แม่นยำที่สุดตามที่ไฮไลต์โดย @roaima หากไม่มี\.pngไฟล์ที่มีการEscape ชื่อa_png.pngจะแสดงเป็น: a_.


การใช้ls -lอย่างที่คุณทำจะให้รายละเอียดไฟล์นั่นไม่ใช่สิ่งที่ OP ถาม
Anthon

1

บรรทัดเชลล์แบบง่าย (ksh, bash หรือ zsh; not dash):

set -- *.png; printf '%s\n' "${@%.png}"

ฟังก์ชั่นง่าย ๆ (จากไม่มีส่วนขยาย):

ne(){ set -- *.png; printf '%s\n' "${@%.png}"; }

หรือฟังก์ชั่นที่ลบส่วนขยายใด ๆ ที่ได้รับ (png โดยค่าเริ่มต้น):

ne(){ ext=${1:-png}; set -- *."$ext"; printf '%s\n' "${@%.${ext}}"; }

ใช้เป็น:

ne jpg

หากเอาต์พุตเป็นเครื่องหมายดอกจันจะ*ไม่มีไฟล์ที่มีนามสกุลนั้นอยู่


1

คุณสามารถลองฟีดต่อไปนี้ awk ผลลัพธ์ของ ls superator ของคุณคือ "." และเนื่องจากไฟล์ทั้งหมดของคุณจะมี name.png คุณพิมพ์คอลัมน์แรก:
ls | awk -F"." '{print $1}'


-1

หากคุณมี acccess ถึง sed นี่จะดีกว่าเพราะจะตัดส่วนขยายของไฟล์ล่าสุดไม่ว่าจะเป็นอะไร (png, jpg, tiff, ฯลฯ ... )

ls | sed -e 's/\..*$//'

7
this.is.a.dotty.txtเที่ยวบินสำหรับชื่อไฟล์เช่น ลองs/\.[^.]*$//แทน
roaima
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.