เรียงลำดับเอาต์พุตของ find -exec ls


14

มันเป็นไปได้ที่จะส่งออกของfind … -exec ls -ls ;เรียงตามลำดับตัวอักษรโดยชื่อไฟล์?

นี่คือคำสั่ง cron ของฉัน:

find /home/setefgge/public_html -type f -ctime -1 -exec ls -ls {} \;

คำสั่งนี้ใช้งานได้ดีส่วนใหญ่ แต่ผลลัพธ์จะไม่เรียงตามลำดับที่มีความหมายใด ๆ มันจะมีประโยชน์มากหากพวกเขาจะเรียงตามฟิลด์ชื่อไฟล์


1
ใช้ zsh หรือไม่ ls -ls **/*(.)
Kevin

@ เควินไม่มาก - lsจะเรียงลำดับ
Gilles 'หยุดความชั่วร้าย'

คำตอบ:


14

ฉันสมมติว่าชื่อไฟล์ของคุณไม่มีการขึ้นบรรทัดใหม่

find /home/setefgge/public_html -type f -ctime -1 -exec ls -nls {} + | sort -k 10

ใช้+แทนการ;บอกเลิก-execการกระทำที่จะทำให้มันเร็วขึ้นโดย batching lsสวดของ คุณสามารถเรียงลำดับโดยการไพพ์ผ่านsortคำสั่ง บอกให้เริ่มเรียงลำดับที่ฟิลด์ 10 (9 รายการแรกคือเมตาดาต้า: บล็อกสิทธิ์จำนวนลิงก์ผู้ใช้กลุ่มขนาดและฟิลด์วันที่ / เวลา 3) ตัวเลือก-nบอกlsให้ใช้ค่าตัวเลขสำหรับผู้ใช้และกลุ่มซึ่งหลีกเลี่ยงความเสี่ยงของชื่อผู้ใช้หรือกลุ่มที่มีช่องว่าง

อีกทางเลือกหนึ่งด้วย zsh คุณสามารถหลีกเลี่ยงข้อสันนิษฐานเกี่ยวกับชื่อใด ๆ ได้โดยใช้ตัวระบุแบบกลมเพื่อรวบรวมและเรียงลำดับไฟล์และzargsเรียกใช้lsหลายครั้งหากบรรทัดคำสั่งยาวเกินไป คุณต้องใช้ GNU ls(โดยเฉพาะตัว-fเลือก) เพื่อหลีกเลี่ยงการเรียงลำดับใหม่ด้วยls(อีกวิธีหนึ่งจะเลียนแบบlsด้วย zsh's zstat)

autoload -U zargs
zargs -- /home/setefgge/public_html/**/*(.c-2) -- ls -lnsf

ขอบคุณมาก! การใช้คำสั่งแรกที่คุณส่งทำการเรียงลำดับ จำนวนจะยังคงเป็น 10 หรือไม่ถ้าฉันใช้เส้นทางที่สั้นกว่านี้ ตัวอย่างเช่นหากฉันใช้คำสั่งเดียวกันจาก / home / setefgge แทนที่จะเป็น public_html
MaJ

@MaJ 10 คือจำนวนฟิลด์ที่ข้าม แต่ไม่มีอะไรเกี่ยวข้องกับขนาดของชื่อไฟล์
Gilles 'หยุดความชั่วร้าย'

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

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

1

ทำไมไม่ไพพ์ผลลัพธ์ของ find through sort แล้วดำเนินการ ls สำหรับแต่ละบรรทัด?

find . -type f -ctime -1 | sort | while IFS= read -r filename; do ls -ls "$filename"; done

1

POSIX มีสิ่งนี้จะพูดเกี่ยวกับวันที่ในls -lรายชื่อ ong:

<date and time>ฟิลด์ต้องมีวันที่และเวลาที่เหมาะสมเมื่อไฟล์ถูกแก้ไขล่าสุด ในโลแคล POSIX ฟิลด์จะเทียบเท่ากับเอาต์พุตของคำสั่ง date ต่อไปนี้:

date "+%b %e %H:%M"

... หากไฟล์ถูกแก้ไขในช่วงหกเดือนที่ผ่านมาหรือ:

date "+%b %e %Y"

การพิจารณาเรื่องนี้และเพื่อให้แน่ใจว่าหากมีบรรทัดใหม่ในชื่อไฟล์พวกเขาจะกลมกลืนกับls -qตัวเลือกPOSIX ที่ระบุอย่างเหมาะสมมันค่อนข้างง่ายในการจัดเตรียม regex สำหรับlsผลลัพธ์โดยfindที่ไม่ต้องทำอะไรเลย:

d=$(date "+%b %e") y=$(date --date=yesterday "+%b %e")
echo "$d" "$y"

###OUTPUT###
Jul  5 Jul  4

grepสำหรับสิ่งนั้นและคุณจะส่งคืนเฉพาะบรรทัดที่มีสตริงที่แสดงวันที่วันนี้หรือเมื่อวาน คำสั่งต่อไปนี้เพิ่มไปเล็กน้อย:

ls -alRcq | sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

ls ตัวเลือกประกอบด้วย:

  1. -a ส่งคืนไฟล์ทั้งหมดในไดเรกทอรีรวมถึงไฟล์ที่ขึ้นต้นด้วย .dot
  2. -l รายชื่อยาว
  3. -R รายการไดเรกทอรีลูกทั้งหมดซ้ำ
  4. -c แสดงเวลาแก้ไขมากกว่าเวลาเข้าถึง
  5. -qส่งคืนเชลล์ glob ?แทนที่จะเป็นอักขระที่ไม่สามารถพิมพ์ได้หรือ\tab ในชื่อไฟล์

ผลลัพธ์เหล่านั้นจะถูกส่งผ่าน|pipeไฟล์sedที่ตรงเท่านั้น:

  1. บรรทัดว่างนำหน้าชื่อพา ธ และบรรทัดต่อไปนี้
  2. บรรทัดที่ขึ้นต้นด้วย- (ในคำอื่น ๆ - ไม่ใช่dสำหรับไดเรกทอรี)ที่มีของคุณด้วยdateด้วย
  3. มันไม่ได้พิมพ์บรรทัดชื่อพา ธ แม้ว่าจะไม่มีไดเรกทอรีที่พวกเขาตั้งชื่อไฟล์ที่คุณกรองไว้

ผลลัพธ์มีลักษณะดังนี้:

ls -alRcq --color=always | 
sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

###OUTPUT###
.:
-rw------- 1 mikeserv mikeserv   2086 Jul  4 10:52 .bash_history
-rw------- 1 mikeserv mikeserv   2657 Jul  4 15:20 .lesshst
-rw-r--r-- 1 mikeserv mikeserv    681 Jul  5 05:18 .zdirs
-rw------- 1 mikeserv mikeserv 750583 Jul  5 08:28 .zsh_history
-rw-r--r-- 1 mikeserv mikeserv    166 Jul  4 23:02 Terminology.log
-rw-r--r-- 1 mikeserv mikeserv 433568 Jul  4 13:34 shot-2014-06-22_17-10-16.jpg
-rw-r--r-- 1 mikeserv mikeserv 445192 Jul  4 13:34 shot-2014-06-22_17-11-06.jpg

./.cache/efreet:
-rw------- 1 mikeserv mikeserv  37325 Jul  4 22:51 desktop_localhost_C.eet
-rw------- 1 mikeserv mikeserv  37325 Jul  4 23:30 desktop_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 22:51 desktop_util_localhost_C.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 23:30 desktop_util_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  16037 Jul  4 23:30 icon_themes_localhost.eet
-rw------- 1 mikeserv mikeserv   3117 Jul  4 23:30 icons___efreet_fallback_localhost.eet
-rw------- 1 mikeserv mikeserv 768039 Jul  4 23:30 icons_gnome_localhost.eet
-rw------- 1 mikeserv mikeserv  18589 Jul  4 23:30 icons_hicolor_localhost.eet

./.config:
-rw-r--r-- 1 mikeserv mikeserv   30 Jul  4 19:10 pavucontrol.ini

./.config/chrome:
-rw-r--r-- 1 mikeserv mikeserv 94332179 Jul  4 13:36 conf.tar.lz4.bak

ใช่มันใช้งานได้กับLS_COLORS- ซึ่งอาจเป็นลำดับความสำคัญต่ำสำหรับcronหลักสูตรของคุณแต่เฮ้ตัวเลือกของคุณเปิดอยู่

ไม่ว่าในกรณีใด ๆ ข้อเสนอนี้มีข้อได้เปรียบที่สำคัญกว่าโซลูชันที่เป็นไปได้อื่น ๆ

  1. ในสถานที่แรกfind+ lsเกี่ยวข้องกับการร้องขอหลายรายการ - นี่เกี่ยวข้องกับlsกระบวนการเดียวเท่านั้นและนี่คือสาเหตุที่มันสามารถจัดเรียงทุกอย่างได้อย่างน่าเชื่อถือ - ซึ่งเป็นค่าเริ่มต้น - และsortเป็นสิ่งเสริมด้วยเช่นกัน

  2. การแก้ปัญหาใด ๆ ที่เกี่ยวข้องfindและsortและlsการทำงานทั้งหมดสองครั้ง lsและfindทั้งคู่จะแก้ไขชื่อพา ธ และstatทุกไฟล์ lsและsortจะจัดเรียงผลลัพธ์ทั้งหมด lsมันอาจจะดีที่สุดคือแทนที่จะใช้เพียงครั้งเดียว

  3. แน่นอนว่ามันมีdateและsedบางส่วนของคำตอบนี้ สิ่งสำคัญที่ควรทราบคือคุณทำส่วนที่ยากและรับ regex ก่อน - และเพียงครั้งเดียว - หลังจากนั้นคุณจะตัดรายการผลลัพธ์เพียงรายการเดียวแทนที่จะพูดว่ารับผลลัพธ์รับผลลัพธ์จัดเรียงผลลัพธ์และเรียงลำดับผลลัพธ์

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

มีสองกรณีที่คำสั่งดังกล่าวอาจทำให้คุณมีปัญหา ครั้งแรกที่เกี่ยวข้องกับ?globs ในชื่อไฟล์ - ในขณะที่มันเป็นวิธีการแก้ปัญหาที่มีประสิทธิภาพมากขึ้นกว่าที่เสนออื่น ๆ ที่นี่และโอกาสที่คุณจะพบ a ?ทั้งหมดมีขนาดเล็กพอในตัวเองมีความเป็นไปได้ที่จะแก้ไข globs เหล่านั้น สามารถจับคู่ชื่อไฟล์ได้มากกว่าหนึ่งชื่อ โปรดดูสิ่งนี้สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้

ความเป็นไปได้อื่น ๆ นั้นเกี่ยวข้องกับผลบวกที่ผิดพลาด - ตัวอย่างเช่นหากคุณมีชื่อไฟล์ที่ตรงกับdateสตริงที่เรากำลังค้นหาgrepแต่ที่ไม่ได้แก้ไขจริงในวันใดวันหนึ่ง ฉันไม่ได้นับว่าเป็นปัญหา แต่ถ้าเป็นเช่นนั้นถามเกี่ยวกับมันและฉันอาจช่วยให้คุณสร้าง regex ที่เฉพาะเจาะจงมากขึ้นเพื่อจัดการกับเรื่องนี้


0

คุณสามารถใช้การรวมกันของ find, xargs และ ls

นี่คือคำสั่งตัวอย่าง: find . -type f -print0 | xargs -0 ls -lt

  • find จะค้นหาไฟล์ทั้งหมดซ้ำ ๆ ในไดเรกทอรีปัจจุบัน
  • xargs จะส่งรายการของไฟล์นี้ไปยังlsคำสั่งในการโทรครั้งเดียว (ให้findผลตอบแทนน้อยกว่าARG_MAXไฟล์)
  • ls -lt จะเรียงลำดับไฟล์เหล่านี้ตามเวลาและจัดรูปแบบผลลัพธ์

เพื่อดึงระบบของARG_MAXคุณคุณสามารถพิมพ์:

$ getconf ARG_MAX
> 2621440

-1
ls -l $(find /home/setefgge/public_html -type f -ctime -1 | sort)

1
lsทำการเรียงลำดับของตัวเองดังนั้นการวางท่อส่งfindผ่านของsortจึงไม่มีประโยชน์ นอกจากนี้คำสั่ง mangles ของคุณจะมีชื่อไฟล์ที่มีช่องว่าง (ในหมู่อื่น ๆ ) และจะล้มเหลวหากมีชื่อไฟล์มากเกินไป
Gilles 'หยุดชั่วร้าย'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.