แยกส่วนของเส้นที่มีรูปแบบเฉพาะโดยใช้ awk, sed


18

ฉันมีคำถามเกี่ยวกับตัวดำเนินการ awk / sed ฉันมีไฟล์ขนาดใหญ่ที่มีชุดของบรรทัดต่อไปนี้ซ้ำแล้วซ้ำอีก

Expression loweWallrhoPhi :  sum=-6.97168e-09
Expression leftWallrhoPhi :  sum=6.97168e-09
Expression lowerWallPhi :  sum=-5.12623e-12
Expression leftWallPhi :  sum=5.12623e-12
Expression loweWallrhoUSf :  sum=-6.936e-09
Expression leftWallrhoUSf :  sum=6.97169e-09
Expression lowerWallUSf :  sum=-5.1e-12
Expression leftWallUSf :  sum=5.12624e-12

ฉันต้องการแยกค่าหลังจากผลรวมในแต่ละกรณีในไฟล์แยกกัน เป็นไปได้ไหมที่จะทำในครั้งเดียว?

คำตอบ:


26

ด้วยคำสั่ง grep:

grep -oP 'sum=\K.*' inpufile > outputfile

grep พร้อม-Pพารามิเตอร์ (perl-regexp) รองรับ\Kซึ่งใช้เพื่อละเว้นอักขระที่ตรงกันก่อนหน้านี้

ด้วยคำสั่ง awk:

awk -F"=" '{print $NF}' inputfile > outputfile

Awk NFให้จำนวนฟิลด์ทั้งหมดในระเบียน / บรรทัด ดังนั้นค่าสุดท้ายของนั่นคือหมายเลขเขตข้อมูลสุดท้ายในบันทึก / บรรทัด

ด้วยคำสั่ง sed:

sed 's/^.*sum=//' inpufile > outputfile

^.*=sumแทนที่อักขระทั้งหมด ( .*) ระหว่างการเริ่มต้นบรรทัด ( ^) และอักขระสุดท้าย ( sum=) ด้วย whitespace char

ผลลัพธ์:

-6.97168e-09
6.97168e-09
-5.12623e-12
5.12623e-12
-6.936e-09
6.97169e-09
-5.1e-12
5.12624e-12

หากคุณต้องการบันทึกแต่ละค่าลงในไฟล์แยกต่างหากให้ใช้คำสั่งข้างต้นในลูป while

while read line; do
    echo "$line" | grep -oP 'sum=\K.*'     > $(echo "$line" |awk '{print $2}');
   #echo "$line" | awk -F"=" '{print $NF}' > $(echo "$line" |awk '{print $2}');
   #echo "#line" | sed 's/^.*sum=//'       > $(echo "$line" |awk '{print $2}');
done < file

ซึ่งรวมถึงsum=และที่ไม่เหมือนกับค่าหลังจากsum=
Anthon

OP ต้องการค่าหลังจากผลรวมและคำอธิบาย awk ของ NF นั้นแย่มาก

1
ให้เสร็จสมบูรณ์นี้คำตอบที่ดีมากคุณยังสามารถใช้:cut cut -d'=' -f2 file
fedorqui

นี่เป็นคำตอบที่ดีมาก ฉันชอบมัน. ขอขอบคุณ.
Jaffer Wilson

6

หากฉันเข้าใจคำถามที่คุณต้องการรับเฉพาะค่าหลังจากนั้นอย่างถูกต้อง=และเก็บค่าเหล่านี้ในไฟล์แยกกันโดยยึดตามฟิลด์ที่สอง (?) ถ้าฉันถูกลองสิ่งนี้:

$ awk -F'[ =]' '{print $6>"file_"$2".txt"}' file

ผลลัพธ์:

$ ls -1
  file_leftWallPhi.txt
  file_leftWallUSf.txt
  file_leftWallrhoPhi.txt
  file_leftWallrhoUSf.txt
  file_loweWallrhoPhi.txt
  file_loweWallrhoUSf.txt
  file_lowerWallPhi.txt
  file_lowerWallUSf.txt

$ cat  file_leftWallPhi.txt
  5.12623e-12

@KasiyA ฉันไม่สามารถทำซ้ำปัญหาของคุณด้วย GNU awk 4.0.2 คำสั่งจากคำตอบของฉันยังใช้ได้กับ-cตัวเลือก (โหมดความเข้ากันได้กับ UNIX แบบดั้งเดิมawkที่ส่วนขยาย GNU ถูกปิดใช้งาน) โปรดตรวจสอบว่าคุณได้อัปเดตไฟล์อินพุตเนื่องจากคำถามเดิมได้รับการแก้ไขแล้วและลบบรรทัดว่างเปล่า
jimmij

1

คุณสามารถทำได้โดย sed

sed -E 's/^.* (\S+)\s*:.*=(\S+)/echo "\2" > "\1".txt/' file | bash

สคริปต์ค้นหาข้อมูลสองรายการในบรรทัด:

  1. ระหว่างช่องว่างและ:และควรมีสัญลักษณ์ที่ไม่ใช่ช่องว่าง (มากกว่า 0)
  2. บางคน (มากขึ้นแล้ว 0) สัญลักษณ์ที่ไม่ใช่ช่องว่างหลัง=;

และจัดรูปแบบจากคำสั่งในการดำเนินการซึ่งโอนผ่านไพพ์ไปยัง bash


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