วิธีคัดลอกรายละเอียดจากไฟล์และวางลงในไฟล์ใหม่ได้อย่างไร


11

ฉันมีไฟล์ที่มีรายละเอียดส่วนตัวของฉัน (.txt) ฉันจะคัดลอกเทอร์มินัลจากรายละเอียดเพียงเล็กน้อยจากไฟล์และนำไปเป็น.txtไฟล์ใหม่ได้อย่างไร

ตัวอย่างเช่นถ้านี่คือเนื้อหาของไฟล์:

name : farah age : 23 phone number : 0123 education : degree

ฉันจะคัดลอกเฉพาะอายุและหมายเลขโทรศัพท์และส่งออกไปยัง.txtไฟล์ใหม่ได้อย่างไร


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

คำตอบ:


7

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

ชื่อ: แซลลี่

วันเดือนปีเกิด: 7.31.76

ที่อยู่: 1234 Main St.

SSN: 123-45-6789

คุณสามารถเรียกใช้และมันจะกลับมาgrep Name info.txt Name: Sallyจากนั้นคุณสามารถเปลี่ยนเส้นทางผลลัพธ์ไปยังไฟล์อื่น ดังนั้นการโทร

grep Name info.txt > info2.txt

จะส่งออกบรรทัดไปที่ไฟล์ใหม่ info2.txt หากคุณต้องการต่อท้ายบรรทัดใหม่คุณสามารถทำได้

grep Address info.txt >> info2.txt

มิฉะนั้นไฟล์จะถูกเขียนทับ

คุณสามารถเรียนรู้การใช้โปรแกรมแก้ไขข้อความบรรทัดคำสั่งเช่นvim


2

คุณสามารถใช้grepเพื่อค้นหานิพจน์ทั่วไปในdetails.txtและเปลี่ยนเส้นทางผลลัพธ์ไปยังไฟล์ใหม่

หากบรรทัดทั้งหมดที่คุณต้องการคัดลอกมีบางสิ่งที่เหมือนกันบรรทัดอื่นคุณไม่สามารถใช้:

grep "string in common" details.txt > new.txt

ถ้าไม่ได้คุณจะต้องค้นหาแต่ละบรรทัดคุณต้องการคัดลอกยังคงใช้ grep และผนวกให้พวกเขาnew.txtใช้ในสถานที่ของ>>>


1

นอกจากนี้ยังมีตัวแก้ไขที่ทำงานในเทอร์มินัลเช่น nano, vi และ emacs

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


1

สมมติว่าไฟล์อินพุตdetails.txtมี:

name: farah
age: 23
phone number: 0123
education: degree

คุณสามารถเลือกบรรทัด "ชื่อ" และ "โทรศัพท์" โดยขยาย grep และเปลี่ยนเส้นทางไปที่ new.txt:

grep -E "age:|phone number:" details.txt > new.txt

สิ่งนี้จะสร้าง new.txt ด้วย:

age: 23
phone number: 0123

มันทำงานอย่างไร:

Grep พิมพ์เส้นที่ตรงกันเท่านั้น -Eตัวเลือกเปิดใช้งาน regexp ขยายที่ช่วยให้คุณเป็นไปได้ในการใช้งาน|(ทางเลือก) อย่าลืมอ้างอิงรูปแบบทั้งหมดดังนั้น|grep จะถูกตีความ มิฉะนั้นเชลล์จะพยายามตีความ คุณไม่ต้องการสิ่งนี้ที่นี่


1

ไฟล์ที่คุณแสดงมีรายละเอียดทั้งหมดในหนึ่งบรรทัด:

name : farah age : 23 phone number : 0123 education : degree

ฉันคิดว่าคุณสามารถใส่ฮาร์โค้ดและage :อื่น ๆ ลงในคำสั่งได้ แต่ข้อความที่ตามมาจะแตกต่างกันไปและรายละเอียดอาจไม่อยู่ในลำดับที่กำหนดหรือติดกัน

คุณสามารถแยกชิ้นส่วนของเส้นที่มีgrep's -oธง สิ่งนี้จะพิมพ์เฉพาะส่วนที่จับคู่ไม่ใช่ทั้งเส้น

หากคุณต้องการรวมage :และphone number :ชิ้นส่วนคุณสามารถใช้การ-eตั้งค่าสถานะเพื่อระบุการแข่งขันหลายรายการหรือการสลับ

$ grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file
age : 23
phone number : 0123

นิพจน์[^ ]*หมายถึงจำนวนอักขระที่ไม่ใช่ช่องว่างดังนั้นจึงจับคู่อักขระหลังจากage :ถึงช่องว่างถัดไป

แทนที่fileด้วยชื่อไฟล์ที่มีรายละเอียดของคุณ คุณสามารถเขียนไฟล์ใหม่โดยเปลี่ยนเส้นทางเอาต์พุตไปยังไฟล์ใหม่ด้วย>โอเปอเรเตอร์ดังนี้:

grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file > outfile

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

นี่คือตัวอย่างของการสลับ เราใช้การ-Eตั้งค่าสถานะเพื่อบอกgrepให้ใช้การขยายเพิ่มเติม ไวยากรณ์(pattern1|pattern2)- แมตช์นี้และpattern1 / หรือ pattern2หากพบอย่างใดอย่างหนึ่งก็จะถูกพิมพ์ (ไม่ว่าจะพบคนอื่นหรือไม่) ตอนนี้ฉันกำลังใช้+ความหมายอย่างน้อยหนึ่งในตัวละครก่อนหน้าแทนที่จะเป็น*ความหมายศูนย์ของตัวละครก่อนหน้าหรือมากกว่านั้น ในบริบทนี้พวกเขาทำงานได้ดีอย่างเท่าเทียมกัน

$ grep -Eo '(age : [^ ]+|phone number : [^ ]+)' file
age : 23 
phone number : 0123 

หากคุณต้องการละเว้นage :และphone number:ส่วนต่าง ๆ คุณสามารถใช้การ-Pตั้งค่าสถานะเพื่อขอgrepให้ใช้นิพจน์ทั่วไปที่เข้ากันได้กับ Perl สิ่งนี้สนับสนุนการสลับและวิธีการจับคู่ข้อความหลังรูปแบบที่กำหนด:

$ grep -Po '(age : \K[^ ]+|phone number : \K[^ ]+)' file
23
0123

หากคุณต้องการจัดรูปแบบข้อความแตกต่างกันคุณสามารถใช้sedตัวอย่างเช่น:

$ sed -r 's/.*(age) : ([^ ]*).*(phone number) : ([^ ]*).*/\1:\2 | \3:\4/' file
age:23 | phone number:0123

ขึ้นอยู่กับว่าageจะมาก่อนphone numberดังนั้นโปรดปรับให้เหมาะสมหากไม่ใช่ในกรณีนี้ หากคุณไม่สามารถพึ่งพาคำสั่งซื้อคุณสามารถใช้คำสั่งที่ซับซ้อนมากนี้:

$ sed -r 's/(.*)(phone number : [^ ]+)(.*) .*/\2 \1\4/; s/(phone number) : ([^ ]+) .*(age) : ([^ ]+).*/\1: \2 | \3: \4/' file
phone number: 0123 | age: 23

นี่เป็นการจัดเรียงบรรทัดใหม่เพื่อให้phone number :ส่วนมาก่อนทุกบรรทัดจากนั้นทำการแทนที่ครั้งที่สองเพื่อเลือกรายละเอียดที่ต้องการ ฉันเป็นหนี้เทคนิคที่ใช้ที่นี่เพื่อคำตอบนี้โดย Muru

หมายเหตุเกี่ยวกับsedคำสั่งที่ไม่ครอบคลุมโดยคำอธิบายก่อนหน้า

  • -rใช้ Extended regex สำหรับคำสั่งที่อ่านได้มากขึ้น (GNU sedเข้าใจ-Eด้วยความหมายเดียวกัน)
  • s/old/new/แทนที่oldด้วยnew
  • (pattern)บันทึกpatternไปยังการอ้างอิงในภายหลังด้วย\1หรือ\2อื่น ๆ (สอดคล้องกับลำดับจากซ้ายไปขวาที่กลุ่มการดักจับเกิดขึ้น - โปรดทราบว่าsedจะเก็บได้ถึง 7 รายการเท่านั้น!)
  • .อักขระใด ๆ จึง.*แสดงถึงจำนวนอักขระใด ๆ
  • ; แยกคำสั่งเช่นเดียวกับในเปลือก
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.