ฉันจะใช้การตัดเพื่อคั่นด้วยช่องว่างหลายช่องได้อย่างไร


23

ฉันต้องการรับคอลัมน์สุดท้ายของตัวอย่างนี้:

[  3]  1.0- 2.0 sec  1.00 MBytes  8.39 Mbits/sec
[  3]  2.0- 3.0 sec   768 KBytes  6.29 Mbits/sec
[  3]  3.0- 4.0 sec   512 KBytes  4.19 Mbits/sec
[  3]  4.0- 5.0 sec   256 KBytes  2.10 Mbits/sec
...

ถ้าฉันใช้

cut -d\  -f 13

ฉันเข้าใจ

Mbits/sec
6.29
4.19
2.10

เพราะบางครั้งมีช่องว่างเพิ่มเติมในระหว่าง


คอลัมน์สุดท้ายคือMbits/secสิ่งที่คุณต้องการหรือ 2 คอลัมน์สุดท้าย?
terdon

1
ฉันต้องการได้รับคอลัมน์สุดท้ายที่ 2 เฉพาะตัวเลข
rubo77

คำตอบ:


17

ในการตอบคำถามของคุณอย่างแท้จริง:

sed 's/   */:/g' | cut -d : -f 5

หรือ

awk -F '  +' '{print $5}'

แต่นั่นจะไม่ทำถ้าตัวเลขในวงเล็บถึง 10 เป็นต้นถ้าคุณสนใจเฉพาะตัวเลขคุณสามารถลบทุกอย่างออกได้

sed 's/[^.0-9][^.0-9]*/:/g' | cut -d : -f 6

ใช่แน่ใจว่าตัวเลขเท่านั้น แต่เฉพาะตัวอย่างที่ 3 ของคุณทำงานได้อย่างถูกต้อง
rubo77

@ rubo77 ใช้งานได้สำหรับฉัน สองตัวอย่างแรกทำตามที่คุณขอในชื่อของคุณ หรือว่าคุณต้องการถอดหน่วยออกด้วย? ในกรณีนั้นให้เพิ่ม| sed 's/ .*//'ในตอนท้ายของสองตัวอย่างแรก แน่นอนมีวิธีอื่น ๆ อีกมากมายที่จะทำมัน
Gilles 'ดังนั้นหยุดความชั่วร้าย'

สั้นลงเล็กน้อย+แทน*: cat test | sed 's / [^. 0-9] \ + /: / g' | ตัด -d: -f 6
rubo77

@ rubo77 หาก sed ของคุณรองรับนั่นก็คือ สนับสนุนโดย GNU และ BusyBox แต่ไม่รองรับเช่น BSD หรือ Solaris POSIX ระบุ+และ?ใน ERE แต่ทิ้ง\+และ\?อยู่ใน BRE ไม่ได้กำหนด
Gilles 'หยุดความชั่วร้าย'

22

หากเราใช้trคำสั่งพร้อมกับตัวเลือกการบีบ ( -sแฟล็ก) เพื่อแปลงช่องว่างที่ต่อเนื่องกันหลายรายการเป็นช่องว่างเดียวแล้วดำเนินcutการกับช่องว่างเป็นตัวคั่น - เราสามารถเข้าถึงคอลัมน์ที่ต้องการซึ่งมีตัวเลข

อ้างถึงรหัส snipped ตะโกน:

cat file | tr -s ' ' | cut -d ' ' -f 8


4
คำตอบนี้ควรจะสูงกว่า มันเป็นเรื่องไกลโดยวิธีที่ง่ายและสามารถอ่านได้มากที่สุด
ลุคเดวิส

5

คำสั่งเหล่านี้จะพิมพ์คอลัมน์สุดท้ายของไฟล์ที่คั่นด้วยช่องว่าง:

  • awk '{print $NF}' file

    ในawk, NFคือจำนวนของเขตข้อมูลและ$NFเป็นเขตที่ผ่านมา

  • perl -lane 'print $F[$#F]' file

    -aแยกไฟล์บนช่องว่างออกเป็นอาเร@Fย์$#Fคือจำนวนองค์ประกอบในอาเรย์$F[$#F]เป็นองค์ประกอบสุดท้าย -nวิธีการอ่านไฟล์ที่ได้รับในบรรทัดคำสั่งและใช้สคริปต์ที่ผ่านไป-eแต่ละบรรทัด -lเพียงเพิ่มอักขระขึ้นบรรทัดใหม่ ( \n) ในแต่ละprintข้อความสั่ง

  • sed 's/.* //g'

    นิพจน์ทั่วไปอย่างง่ายที่จับคู่ทุกอย่างกับช่องว่างสุดท้ายและลบออกโดยเหลือเพียงคอลัมน์สุดท้าย

  • rev file | cut -d' ' -f 1 | rev

    revย้อนกลับเอาต์พุตดังนั้นฟิลด์สุดท้ายคือฟิลด์แรกcutด้วยพื้นที่ตัวคั่นเพื่อพิมพ์และrevกลับข้อความเป็นปกติ นี้ได้รับรางวัล' T ทำงานถ้าคุณมีช่องว่างต่อเนื่อง

จากข้อมูลที่คุณป้อนฉันคาดเดาว่าคุณไม่ต้องการคอลัมน์สุดท้าย แต่เป็นคอลัมน์สุดท้ายหรือหนึ่งคอลัมน์สุดท้าย ในกรณีนี้ใช้สิ่งเหล่านี้เพื่อพิมพ์ 2 ( 8.39 Mbits/sec) ล่าสุด

awk '{print $(NF-1),$NF}' file 
perl -lane 'print "$F[$#F-1] $F[$#F]"' file 
sed 's/.* \(.* .*\)/\1/' file 
rev file | cut -d' ' -f 1,2 | rev

และสิ่งเหล่านี้เพื่อพิมพ์ penultimate ( 8.39):

awk '{print $(NF-1)}' file 
perl -lane 'print $F[$#F-1]' file 
sed 's/.* \(.*\) .*/\1/' file 
rev file | cut -d' ' -f 2 | rev

4

คุณไม่สามารถแยกการใช้ช่องว่างที่เกิดขึ้นหลายครั้งได้ cutตามคู่มือ:

ฟิลด์เอาต์พุตถูกคั่นด้วยการเกิดขึ้นครั้งเดียวของอักขระตัวคั่นฟิลด์

เว้นแต่ข้อความจะถูกคั่นด้วยจำนวนเดียวกันหรือคุณใช้ trเพื่อลบส่วนที่เกินออก

มิฉะนั้นการใช้เครื่องมือทางเลือกเช่นawk,sedexหรือ

ตัวอย่างเช่น:

ex -s +'%norm $2Bd0' +%p +q! foo.txt

แทนที่+q!ด้วย-cwqเพื่อบันทึกการเปลี่ยนแปลงแบบแทนที่


0

ใช้ Perl หนึ่งซับเช่น:

perl -lane 'print $F[-2]' input_file

คำอธิบาย:

ตัวเลือก-eทำให้ล่าม perl เพื่อค้นหาสคริปต์แบบอินไลน์มากกว่าในไฟล์

ตัวเลือกที่-nทำให้การป้อนข้อมูล (ไฟล์หรือ STDIN จากไปป์) ที่จะอ่านทีละบรรทัด

ตัวเลือก -lแยกตัวคั่นเรคคอร์ดอินพุต (ขึ้นอยู่กับระบบปฏิบัติการ, ขึ้นบรรทัดใหม่บน UNIX ตามค่าเริ่มต้น) หลังจากอ่านบรรทัดแล้วเพิ่มเข้าไปที่ส่วนท้ายของทุก ๆprint

ตัวเลือก-aทำให้แต่ละบรรทัดอินพุตถูกแยกบนช่องว่างเป็นอาร์เรย์@Fและ$F[-2]เป็นองค์ประกอบที่สองนับจากจุดสิ้นสุดซึ่งเป็นฟิลด์ที่คุณต้องการ คุณยังสามารถใช้$F[$#F-1]โดยที่$#Fเป็นดัชนีสุดท้ายของอาร์เรย์@Fซึ่งอ่านได้น้อยกว่าเล็กน้อย

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