วิธีรับคอลัมน์ที่สองจากเอาต์พุตคำสั่ง?


152

เอาต์พุตของคำสั่งของฉันเป็นดังนี้:

1540 "A B"
   6 "C"
 119 "D"

คอลัมน์แรกจะเป็นตัวเลขเสมอตามด้วยช่องว่างแล้วจึงเป็นสตริงที่มีเครื่องหมายคำพูดคู่

จุดประสงค์ของฉันคือการได้รับคอลัมน์ที่สองเท่านั้นเช่น:

"A B"
"C"
"D"

ฉันตั้งใจจะใช้<some_command> | awk '{print $2}'เพื่อให้บรรลุสิ่งนี้ แต่คำถามก็คือค่าบางค่าในคอลัมน์ที่สองมีช่องว่างซึ่งเป็นตัวคั่นเริ่มต้นสำหรับawkแยกเขตข้อมูล ดังนั้นผลลัพธ์จะเลอะ:

"A
"C"
"D"

ฉันจะรับค่าคอลัมน์ที่สองได้อย่างไร (ด้วยเครื่องหมายคำพูดคู่) อย่างสะอาด?



1
ฉันพยายามใช้awk '{$1=""; print $0}'แต่ก็ยังมีตัวละครที่เป็นพื้นที่สีขาว sed '/^ //'มันอาจจะถูกลบออกโดย กระนั้นสิ่งนี้สามารถทำได้ด้วยawkหรือ
Qiang Xu

คำตอบ:


29

หรือใช้ sed & regex

<some_command> | sed 's/^.* \(".*"$\)/\1/'

cmd ที่สั้นลงในขณะที่คุณไม่จำเป็นต้องใช้เครื่องหมายเริ่มต้นและจุดสิ้นสุด:<some_command> | sed 's/.* \(".*"\)/\1/'
Timo

197

ใช้-F [field separator]เพื่อแบ่งบรรทัดบน"s:

awk -F '"' '{print $2}' your_input_file

หรือสำหรับอินพุตจากไปป์

<some_command> | awk -F '"' '{print $2}'

เอาท์พุท:

A B
C
D

3
นี่เป็นสิ่งที่ดี แต่ฉันยังต้องการคำพูดโดยรอบเดิม ทำได้หรือไม่ ขอบคุณ
Qiang Xu

5
คุณสามารถโกงและเปลี่ยนการพิมพ์ของ awk เป็น'{print "\""$2"\""}'
Alex

ใช่งานนี้ ขอบคุณมากอเล็กซ์! โดยคำพูดมากมาย :)
Qiang Xu

@Alex คุณสามารถอธิบายวิธีใช้เครื่องหมายคำพูดคู่และแบ็กสแลชเพื่อให้ได้สิ่งที่ op ต้องการ
Timo

1
@Timo "\"" + $2 + "\""คำพูดและเครื่องหมายการสลายสามารถจินตนาการเป็น เครื่องหมายอัญประกาศล้อมรอบกำลังระบุสิ่งที่จะผนวกเข้ากับเอาต์พุตและเครื่องหมายคำพูดที่ใช้ Escape ( \") กำลังถูกพิมพ์ ที่จะช่วยให้เห็นภาพนี้เป็นสิ่งที่มันจะมีลักษณะเช่นถ้าเราต้องการที่จะเพิ่มพื้นที่ว่างรอบ ๆแทนเครื่องหมายคำพูด:$2 '{print " "$2" "}'นอกจากนี้เรายังสามารถเพิ่มรูปแบบระยะห่างที่จะทำให้มันง่ายขึ้นเล็กน้อยเพื่อ grok:'{print " " $2 " "}'
ทอม

80

หากคุณสามารถใช้สิ่งอื่นที่ไม่ใช่ 'awk' ให้ลองใช้วิธีนี้แทน

echo '1540 "A B"' | cut -d' ' -f2-

-dเป็นตัวคั่น-fคือฟิลด์ที่จะตัดและด้วย-f2- เราตั้งใจจะตัดฟิลด์ที่ 2 จนถึงจุดสิ้นสุด


สิ่งนี้ช่วยให้ฉันพยายามทำสิ่งต่อไปนี้ (ดึงข้อมูลการยอมรับรหัสของไฟล์เป็น git): git annotate myfile.cpp | grep '2016-07' | หัว -1 | cut
-f1

2
นี่เป็นสิ่งที่ดี แต่ไม่ได้ผลหากตัวคั่นมีความยาวมากกว่าหนึ่งอักขระ นั่นคือสิ่งที่โซลูชัน awk ใช้ประโยชน์ได้
smac89

2
ทำไมไม่ใช้พื้นที่หลังจาก-d? มันดูแปลกไปหน่อย
Chris Stryczynski

43

สิ่งนี้ควรใช้เพื่อดึงคอลัมน์เฉพาะออกจากเอาต์พุตคำสั่ง "อิมเมจ docker":

REPOSITORY                          TAG                 IMAGE ID            CREATED             SIZE
ubuntu                              16.04               12543ced0f6f        10 months ago       122 MB
ubuntu                              latest              12543ced0f6f        10 months ago       122 MB
selenium/standalone-firefox-debug   2.53.0              9f3bab6e046f        12 months ago       613 MB
selenium/node-firefox-debug         2.53.0              d82f2ab74db7        12 months ago       613 MB


docker images | awk '{print $3}'

IMAGE
12543ced0f6f
12543ced0f6f
9f3bab6e046f
d82f2ab74db7

นี่จะพิมพ์คอลัมน์ที่สาม


คุณเคยเห็นภาพจากนักเทียบท่ามาบ้างไหม awk '{พิมพ์ $ 5}' หรือไม่
Shashi Ranjan

17

คุณไม่ต้องการ awk สำหรับสิ่งนั้น การใช้งานreadใน Bash shell ควรจะเพียงพอเช่น

some_command | while read c1 c2; do echo $c2; done

หรือ:

while read c1 c2; do echo $c2; done < in.txt



0
#!/usr/bin/python
import sys 

col = int(sys.argv[1]) - 1

for line in sys.stdin:
    columns = line.split()

    try:
        print(columns[col])
    except IndexError:
        # ignore
        pass

จากนั้นสมมติว่าคุณตั้งชื่อสคริปต์เป็น co พูดทำสิ่งนี้เพื่อให้ได้ขนาดของไฟล์ (ตัวอย่างสมมติว่าคุณใช้ Linux แต่สคริปต์นั้นเป็นระบบปฏิบัติการอิสระ): -

ls -lh | co 5

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