แท็บคั่นค่าใน awk


92

ฉันจะเลือกคอลัมน์แรกจากสตริงที่คั่นด้วย TAB ได้อย่างไร

# echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -F'\t' '{print $1}'

ข้างต้นจะส่งกลับทั้งบรรทัดไม่ใช่แค่ "LOAD_SETTLED" ตามที่คาดไว้

อัปเดต:

ฉันต้องการเปลี่ยนคอลัมน์ที่สามในค่าที่คั่นด้วยแท็บ ต่อไปนี้ใช้ไม่ได้

echo $line | awk 'BEGIN { -v var="$mycol_new" FS = "[ \t]+" } ; { print $1 $2 var $4 $5 $6 $7 $8 $9 }' >> /pdump/temp.txt

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

echo $line | awk -v var="$mycol_new" -F'\t' '{print $1 "," $2 "," var "," $4 "," $5 "," $6 "," $7 "," $8 "," $9 "}' >> /pdump/temp.txt

4
ตื่นแล้ว 'BEGIN {FS = "[\ t] +"}; {print $ 1} '# นี่คือสิ่งที่ฉันกำลังมองหา การค้นหาโดย Google ของฉันถูกต้องหรือไม่ :)
shantanuo

3
ด้วยความคิดเห็นนี้ฉันได้ค้นพบ: awk 'BEGIN {FS="\t"}; {print $1,FS,$2,FS,$3}' myFile.txtเพื่อพิมพ์ค่าที่คั่นด้วยแท็บของสามคอลัมน์แรก

7
หรืออาจจะง่าย ๆawk 'BEGIN {OFS="\t"}; {print $1,$2,$3}'
Josiah Yoder

3
ทั้ง GNU และ BSD awk รองรับ-vการตั้งค่าตัวแปร มันน่าเกลียดที่จะใช้BEGIN {FS="\t"}ภายในโปรแกรมแบบอินไลน์และการสนับสนุนโอเพนซอร์สใด ๆ ที่คุณพยายามทำเช่นนั้นมีแนวโน้มที่จะถูกคัดค้าน เพียง แต่ทำว่าถ้าคุณเขียนแฟ้มโปรแกรม นอกจากนี้ยังไม่ควรใช้-Fแทน-v FS=เนื่องจากข้อหลังทำให้ชัดเจนว่าFSมีการตั้งค่าOFSเท่านั้นไม่ใช่ ความสับสนเกี่ยวกับประเด็นสุดท้ายคือสิ่งที่ทำให้เกิดโพสต์นี้ตั้งแต่แรก นั่นเป็นเหตุผลว่าทำไม "สไตล์ที่ดี" จึงมีความสำคัญ
Bruno Bronosky

1
ได้โปรดไม่มีใครควรทำในสิ่งที่ @ ว้ากแสดงให้เห็น คุณไม่ได้ระบุตัวคั่นฟิลด์ [อินพุต] ในเอาต์พุตของคุณ คุณระบุตัวคั่นฟิลด์เอาต์พุตผ่านOFSตัวแปร
Bruno Bronosky

คำตอบ:


143

คุณต้องตั้งค่าOFSตัวแปร (ตัวคั่นฟิลด์เอาต์พุต) ให้เป็นแท็บ:

echo "$line" | 
awk -v var="$mycol_new" -F $'\t' 'BEGIN {OFS = FS} {$3 = var; print}'

(ตรวจสอบให้แน่ใจว่าคุณอ้าง$lineตัวแปรในคำสั่ง echo)


6
จุดประสงค์ของ $ ใน $ '\ t' คืออะไร?
Amr Mostafa

10
ตอบคำถามของฉันเองจากAdvanced Bash Scripting Guide : โครงสร้างการขยายสตริงที่อ้างถึง $ '... ' เป็นกลไกที่ใช้ค่าฐานแปดหรือฐานสิบหกที่ไม่ได้รับการยกเว้น ... เช่น quote = $ '\ 042'
Amr Mostafa

5
@AmrMostafa เลวร้ายว่าคู่มือมีคำอธิบายที่ทำให้เข้าใจผิดชั้นนำอย่างใดอย่างหนึ่งที่จะคิดว่าคุณทำไม่ได้$ใน$'\t'ไม่จำเป็นต้อง วิกิของ Gregดีกว่า: "ในจำนวนนี้$'...'เป็นคำพูดที่พบบ่อยที่สุดและทำหน้าที่เหมือนกับเครื่องหมายคำพูดเดี่ยวยกเว้นชุดค่าผสมที่ใช้เครื่องหมายแบ็กสแลชจะขยายตามที่ระบุโดยมาตรฐาน ANSI C"
Cristian Ciupitu

9
ในการมองย้อนกลับ$'\t'ไม่จำเป็น awk เข้าใจสตริง"\t"เป็นอักขระแท็บ
glenn jackman

6
awk -F $'\t' 'BEGIN {OFS = FS} …'เปิดแหล่งที่มาร่วมให้ฉันขอให้คุณกรุณาอย่าส่งสิ่งที่ชอบ awk -v FS='\t' -v OFS='\t' '…'ที่ควรจะเป็น อาจดูเหมือนอวดรู้ แต่การไม่สอดคล้องกันจะเพิ่มโอกาสที่ผู้ร่วมให้ข้อมูลในภายหลังจะแนะนำข้อบกพร่องเนื่องจากพวกเขาเข้าใจรหัสของคุณผิด
Bruno Bronosky

21

ตรวจสอบให้แน่ใจว่าเป็นแท็บจริงๆ! ใน bash คุณสามารถแทรกแท็บโดยใช้C-v TAB

$ echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -F$'\t' '{print $1}'
LOAD_SETTLED


9

ใช้:

awk -v FS='\t' -v OFS='\t' ...

ตัวอย่างจากหนึ่งในสคริปต์ของฉัน

ฉันใช้ตัวแปรFSและOFSเพื่อจัดการไฟล์โซน BIND ซึ่งคั่นด้วยแท็บ:

awk -v FS='\t' -v OFS='\t' \
    -v record_type=$record_type \
    -v hostname=$hostname \
    -v ip_address=$ip_address '
$1==hostname && $3==record_type {$4=ip_address}
{print}
' $zone_file > $temp

นี่เป็นวิธีที่สะอาดและอ่านง่ายในการทำเช่นนี้



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