แยกส่วนของหนึ่งบรรทัดจากไฟล์ที่มี sed


18

ฉันต้องการอ่านส่วนหนึ่งของหนึ่งบรรทัดจากไฟล์ ตัวอย่างเช่น:

POP3_SERVER_NAME = localhost

ฉันต้องการกลับมาlocalhostโดยใช้ sed

ข้อความนี้อยู่ในบรรทัดที่สาม ฉันทำสิ่งนี้เพื่อแยกบรรทัด:

sed -n '3p' installation.sh

ฉันจะแยกเฉพาะlocalhostส่วนได้อย่างไร

คำตอบ:


26

awk อาจเป็นเครื่องมือที่ดีกว่าที่นี่

$ cat test.dat
LINE 1
LINE 2
POP3_SERVER_NAME = localhost

ค้นหาบรรทัดที่มี "POP3_SERVER_NAME"; พิมพ์ฟิลด์สุดท้าย สิ่งนี้ไม่ได้ขึ้นอยู่กับ POP3_SERVER_NAME เสมอที่บรรทัด 3 ซึ่งอาจเป็นสิ่งที่ดี

$ awk '/POP3_SERVER_NAME/{print $NF}' test.dat
localhost

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

$ awk '/^POP3_SERVER_NAME/{print $NF}' test.dat
localhost

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

sed -n -e '/POP3_SERVER_NAME/ s/.*\= *//p' test.dat

2
awkคำสั่งเป็นสิ่งที่ดี - =แต่ถ้าคุณได้มีพื้นที่รอบ POP3_SERVER_NAME=localhostมันจะไม่ทำงาน
Marcel Stör

2
@Marcel, คุณสามารถเปลี่ยนคั่นที่ใช้โดยจากช่องว่างที่จะใช้อย่างอื่นawk -Fตัวอย่างเช่น: -F "="จะใช้=เป็นตัวคั่นในกรณีที่คุณพูดถึง
mattpr

7

แทนที่pคำสั่งด้วยการทดแทนที่ลบส่วนที่ไม่ต้องการของบรรทัด

sed -n '3 s/^[^=]*= *//p' installation.sh

คุณอาจต้องการจับคู่บรรทัดด้วยคำหลักแทนที่จะตามตำแหน่ง

sed -n 's/^ *POP3_SERVER_NAME *= *//p' installation.sh

6

ดูเหมือนว่าคุณจะมีไฟล์กำหนดค่า สิ่งที่คุณสามารถทำได้คล้ายกับสิ่งที่ Adam Siemeon / slm แนะนำ:

sed -nr 's/[^=]+=\s*(.+)$/\1/p' filename

ที่[^=]ไม่รวมทั้งหมด = 'ตัวอักษร+กล่าวว่าหนึ่งหรือมากกว่าของชนิดเดียวกันของตัวละครนี้ตามที่เกิดขึ้นจริง=, \sช่องว่างใด ๆ (รวมทั้งแท็บ\tและสายใหม่\n, \r\nและช่องว่างธรรมดา '' ในขณะที่*วิธีการศูนย์หรือมากกว่าของชนิดเดียวกัน วงเล็บจับสิ่งที่อยู่ภายในเพื่อวางลำดับอักขระที่ตรงกันใน \ 1, \ 2, ... , \ n ตัวยึดตำแหน่งแทนที่$หมายถึงจุดสิ้นสุดของบรรทัดซึ่งตามรูปแบบการแทนที่โดยทั่วไปของ: s/.../.../modifiers. ตัวเลือกบรรทัดคำสั่ง-rย่อมาจาก ไวยากรณ์ regex เพิ่มเติม (เป็นเรื่องของความสะดวกสบาย) และ-nหมายถึงไม่มีอะไรออกจนกว่าหรือเว้นแต่ร้องขอ explcitly โมดิฟายเออร์pพิมพ์ผลลัพธ์

คุณสามารถทำการค้นหาทั่วโลกด้วยการgปรับเช่น:

sed -nr 's/[^=]+=\s*(.+)$/\1 /pg' filename  # note the space after \1

เพื่อที่คุณจะได้รับสตริงคั่นด้วย' '(อาจจะ\n, \tหรือสิ่งที่มีคุณ) ซึ่งคุณสามารถดำเนินการได้อย่างง่ายดาย

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


แก้ไข:

ฉันไม่สามารถแสดงความคิดเห็นได้ที่นี่ในโพสต์ของคนอื่น เมื่อต้องการระบุบรรทัดให้ส่งผ่านหมายเลขบรรทัดในกรณีที่ 3 ของคุณก่อนsหรือก่อนหน้าอักขระอัญประกาศเริ่มต้น (เหมือนกับในกลุ่ม)

sed -nr '3s/[^=]+=\s*(.+)$/\1/p' filename

info sedโปรดดูที่ ตัวอย่างเช่น 3.2 และ 4.7 เป็นที่สนใจของคุณโดยเฉพาะ


5
echo "POP3_SERVER_NAME = localhost" | sed 's/.*= //'
localhost

หรือถ้าคุณมีเนื้อหาในไฟล์:

sed 's/.*= //' somefile.txt
localhost

ตกลง แต่ฉันอ่านในไฟล์ของฉันเช่นนี้: การติดตั้ง sed -n '3p'
Mercer

2
@Mercer - ดูการอัปเดตที่ฉันเพิ่มไว้ในคำตอบ
slm

@ Adam Siemion - ขอบคุณ แต่จะระบุหมายเลขบรรทัดได้อย่างไร?
Mercer

4

คุณสามารถใช้คำสั่ง cut ตั้งค่าขอบเขตเป็น '=' จากนั้นพิมพ์ฟิลด์ที่สองดังนี้:

cut -d'=' -f2

3

มีหลายวิธีในการพิจารณาไฟล์ของคุณเรียกว่าfoobar:

ระบุรูปแบบที่จะค้นหา:

PAT=POP3_SERVER_NAME

แยกโดยใช้ sed

sed -n "/$PAT/p" foobar | sed "s/$PAT = //"

หรือใช้sedและcut

sed -n "/$PAT/p" foobar | cut -d' ' -f3

2

ความสวยงามของ Linux / Unix คือมักจะมีมากกว่าหนึ่งวิธีในการทำบางสิ่งให้สำเร็จ ในกรณีของ op มีวิธีแตกต่างอย่างน้อยสี่วิธีในการแตกชื่อเซิร์ฟเวอร์ POP จากไฟล์:

  1. grep POP3_SERVER_NAME installation.sh | cut -d'=' -f2
  2. grep POP3_SERVER_NAME installation.sh | awk '{print $3}'
  3. grep POP3_SERVER_NAME installation.sh | sed 's/.*= //'
  4. sed -n 's/^.*POP3_SERVER_NAME = //p' installation.sh
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.