จะใช้คำสั่ง "cat" บนเอาต์พุตของคำสั่ง "find" ได้อย่างไร


13

ฉันต้องการเปลี่ยนทิศทางเอาต์พุตของfindคำสั่งไปยังcatคำสั่งเพื่อให้ฉันสามารถพิมพ์ข้อมูลของไฟล์ที่กำหนด

ดังนั้นสำหรับตัวอย่างเช่นถ้าผลลัพธ์ของการค้นหาเป็นแล้วแมวควรจะตีความว่าเป็น/aFile/readme cat ./aFile/readmeฉันจะทำสิ่งนั้นทันทีได้อย่างไร

ฉันต้องใช้ท่อหรือไม่

ฉันลองรุ่นนี้:

cat | find ./inhere -size 1033c 2> /dev/null

แต่ฉันคิดว่ามันผิดอย่างสิ้นเชิงเหรอ? แน่นอนฉันแน่ใจว่าผลลัพธ์เป็นไฟล์เดียวเท่านั้นและไม่ใช่หลายไฟล์

ดังนั้นฉันจะทำอย่างไร ฉันค้นหาใน Google และไม่พบวิธีแก้ปัญหาอาจเป็นเพราะฉันค้นหาไม่ถูกต้อง: P

คำตอบ:


21

คุณสามารถทำได้findโดยใช้การ-execกระทำเพียงอย่างเดียว:

find /location -size 1033c -exec cat {} +

{}จะถูกขยายไปยังไฟล์ที่พบและ+จะช่วยให้เราสามารถอ่านอาร์กิวเมนต์ได้มากเท่าที่เป็นไปได้ต่อการเรียกใช้catเนื่องจาก cat สามารถรับอาร์กิวเมนต์ได้หลายตัว

หากคุณfindไม่มี+นามสกุลหรือคุณต้องการอ่านไฟล์ทีละตัว:

find /location -size 1033c -exec cat {} \;

หากคุณต้องการใช้ตัวเลือกใด ๆcatให้ทำ:

find /location -size 1033c -exec cat -n {} +
find /location -size 1033c -exec cat -n {} \;

ที่นี่ฉันใช้-nตัวเลือกเพื่อรับหมายเลขบรรทัด


ดังนั้นถ้าฉันถูกต้อง: {} เป็นเหมือนตัวแปรที่เก็บไว้ในเอาต์พุตของคำสั่ง find และหลังเครื่องหมาย "+" คุณควรเขียนพารามิเตอร์ cat หรือไม่ ไม่นะ แก้ไข: เอาล่ะคุณแก้ไขโพสต์ของคุณและตอนนี้คุณเพิ่งตอบคำถามของฉัน: P Thanx man! แก้ไขแล้ว!
Eksapsy

@ general656 ตรวจสอบการแก้ไขของฉัน ..
heemayl

1
ความจริงที่ว่าผมไม่ได้รู้เกี่ยวกับcat's -nตัวเลือกที่น่าประหลาดใจฉัน ฉันรักการอ่านคำถามแบบสุ่ม
mazunki

1

การทดแทนคำสั่ง

อีกตัวเลือกหนึ่งคือการใช้คำสั่งเปลี่ยนตัว การห่อคำสั่ง$()จะเรียกใช้คำสั่งและแทนที่คำสั่งด้วยเอาต์พุต

cat $(find ./inhere -size 1033c 2> /dev/null)

จะกลายเป็น

cat ./inhere/file1 .inhere/file3

นี่เทียบเท่าหรือมากกว่ากับการใช้คำสั่งการห่อแบบเก่าด้วยเครื่องหมายขีดหลัง:

cat `find ./inhere -size 1033c 2> /dev/null`

รายละเอียดเพิ่มเติมจากเอกสารที่ลิงก์ด้านบน

Bash ทำการขยายตัวโดยการดำเนินการคำสั่งในสภาพแวดล้อม subshell และแทนที่การทดแทนคำสั่งด้วยเอาต์พุตมาตรฐานของคำสั่งด้วยบรรทัดใหม่ต่อท้ายใด ๆ ที่ถูกลบ บรรทัดใหม่ที่ฝังจะไม่ถูกลบ แต่อาจถูกลบระหว่างการแยกคำ ทดแทนคำสั่ง$(cat file)จะถูกแทนที่ด้วยเทียบเท่า $(< file)แต่ได้เร็วขึ้น

เมื่อรูปแบบ backquote แบบเก่าของการทดแทนที่ใช้ทับขวายังคงมีความหมายที่แท้จริงของมันยกเว้นเมื่อตามด้วย$, หรือ` \backquote แรกที่ไม่ได้นำหน้าด้วย backslash จะยุติการทดแทนคำสั่ง เมื่อใช้$(command)แบบฟอร์มอักขระทั้งหมดระหว่างวงเล็บจะประกอบขึ้นเป็นคำสั่ง ไม่มีใครได้รับการดูแลเป็นพิเศษ

การแทนที่คำสั่งอาจซ้อนอยู่ ในการซ้อนเมื่อใช้รูปแบบ backquote ให้หลีกเลี่ยง backquotes ภายในด้วยเครื่องหมายแบ็กสแลช

หากการแทนที่ปรากฏภายในเครื่องหมายคำพูดคู่การแยกคำและการขยายชื่อไฟล์จะไม่ถูกดำเนินการกับผลลัพธ์

ดูคำตอบอื่น ๆ นี้สำหรับตัวอย่างการใช้งานที่ดี


โปรดทราบว่าถ้าfindพบไฟล์จำนวนมากเกินไปนี้จะสร้าง "รายการอาร์กิวเมนต์ยาวเกินไป" catข้อผิดพลาดลับพยายามที่จะก่อให้เกิด นอกจากนี้ยังจะมีปัญหาในการจัดการชื่อไฟล์ที่มีอักขระช่องว่างและอาจเป็นชื่อไฟล์ที่ประกอบด้วยอักขระชื่อไฟล์ที่ปรากฏ
Kusalananda

-1

สิ่งนี้จะพิมพ์ชื่อและเนื้อหาของไฟล์ข้อความ (ASCII) แบบเรียกซ้ำเท่านั้น

find . -type f -exec grep -Iq . {} \; -print | xargs awk 'FNR==1{print FILENAME ":" $0; }'

อีกหนึ่งความพยายาม

find . -type f -exec grep -Iq . {} \; -printf "\n%p:" -exec cat {} \;

-2

ใช้ pipe และ xargs

find /* -name pg_hba.conf | xargs cat

หากล้มเหลวเนื่องจากไม่มีสิทธิ์คุณสามารถใช้ sudo เพื่อให้แน่ใจว่าคุณมีสิทธิ์ดำเนินการคำสั่ง find ในไดเรกทอรีที่คุณกำลังค้นหา

 sudo find /* -name pg_hba.conf | xargs sudo cat

1
และถ้ามีคนได้สร้างไฟล์ที่เรียกว่าที่จะช่วยให้การถ่ายโอนข้อมูลรากเนื้อหาทั้งหมดของ/tmp/ /dev/urandom /pg_hba.conf /dev/urandomอาจจะเลวร้ายยิ่งขึ้นอยู่กับบริบท xargsแทบจะไม่เคยถูกใช้-0หากไม่มีเลย นอกจากนี้ยังจะดีกว่าsudo xargs xargs sudoและจะดีกว่าที่เป็น/* /
Stéphane Chazelas

1
OP ต้องการใช้ cat เพื่อพิมพ์เนื้อหาไฟล์ใน stdout โดยมีวัตถุประสงค์เพื่อให้บริการโดยแมว คำถามคือวิธีการใช้ cat จากคำสั่ง out put of find เพื่อพิมพ์เนื้อหาของไฟล์ไม่ใช่วิธีการใช้ sudo หรือ find คำสั่งด้านบนแก้คำถามได้ ใช่ xargs -0 เป็นสิ่งเดียวที่สร้างสรรค์ที่คุณชี้ แต่ไม่ได้แสดงการใช้งาน พยายามอย่าหยาบคาย
แอปทำงาน

ขออภัยถ้าปรากฏว่าหยาบ นั่นไม่ใช่ความตั้งใจ ฉันต้องการชี้ให้เห็นข้อ จำกัด คำตอบของคุณแสดงให้เห็นถึงการปฏิบัติที่ไม่ดี ( find|xargsไม่-0ควรถูกแบนจริงๆ) ดังนั้นการลงคะแนน เอาท์พุทของfindโดย-print0ไม่ได้ไม่ได้เป็นกระบวนการที่เชื่อถือ -print0ไม่ได้มาตรฐาน ต้องบอกว่ามาตรฐานsudo find / -name pg_hba.conf -exec cat {} +สามารถทำให้คุณทิ้งเนื้อหาของ/dev/urandom(เช่นถ้ามีคนสร้าง symlink จาก/tmp/pg_hba.confมันและไม่มีวิธีพกพาง่าย ๆ ที่ไม่ได้มีสภาพการแข่งขัน)
Stéphane Chazelas

1
อย่าใช้sudo"ในกรณี" ใช่ไหม?
lindhe

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