บนเชลล์ฉันจะไปที่ awk เมื่อฉันต้องการคอลัมน์ใดคอลัมน์หนึ่ง
สิ่งนี้พิมพ์คอลัมน์ 9 ตัวอย่างเช่น:
... | awk '{print $9}'
ฉันจะบอกให้ awk พิมพ์คอลัมน์ทั้งหมดรวมทั้งและหลังคอลัมน์ 9ไม่ใช่เฉพาะคอลัมน์ 9 ได้อย่างไร
บนเชลล์ฉันจะไปที่ awk เมื่อฉันต้องการคอลัมน์ใดคอลัมน์หนึ่ง
สิ่งนี้พิมพ์คอลัมน์ 9 ตัวอย่างเช่น:
... | awk '{print $9}'
ฉันจะบอกให้ awk พิมพ์คอลัมน์ทั้งหมดรวมทั้งและหลังคอลัมน์ 9ไม่ใช่เฉพาะคอลัมน์ 9 ได้อย่างไร
คำตอบ:
awk '{ s = ""; for (i = 9; i <= NF; i++) s = s $i " "; print s }'
awk -v N=9 '{sep=""; for (i=N; i<=NF; i++) {printf("%s%s",sep,$i); sep=OFS}; printf("\n")}'
cut
หรือperl
เพื่อสิ่งนี้ ใช้สิ่งนี้ก็ต่อเมื่อคุณยืนยันที่จะมีเข้ามาawk
จริงๆ
เมื่อคุณต้องการทำหลายช่องawk
ไม่มีวิธีตรงไปตรงมาในการทำเช่นนี้ ฉันอยากจะแนะนำcut
แทน:
cut -d' ' -f 9- ./infile
เพิ่มตัวคั่นช่องว่างเนื่องจากค่าเริ่มต้นเป็นแท็บ ขอบคุณ Glenn ที่ชี้ให้เห็นสิ่งนี้
find . | xargs ls -l | cut -d' ' -f 9-
ลองคำสั่ง ด้วยเหตุผลบางประการจะนับช่องว่างสองครั้งด้วย ตัวอย่าง: lrwxrwxrwx 1 me me 21 Dec 12 00:00 ./file_a lrwxrwxrwx 1 me me 64 Dec 6 00:06 ./file_b
จะส่งผลให้./file_a 00:06 ./file_b
awk '{print substr($0, index($0,$9))}'
แก้ไข : หมายเหตุจะใช้ไม่ได้หากฟิลด์ใด ๆ ก่อนที่เก้ามีค่าเดียวกับที่เก้า
sed -re 's,\s+, ,g' | cut -d ' ' -f 9-
แทนที่จะจัดการกับช่องว่างความกว้างตัวแปรให้แทนที่ช่องว่างทั้งหมดเป็นช่องว่างเดียว จากนั้นใช้แบบธรรมดาcut
กับสาขาที่สนใจ
มันไม่ได้ใช้ awk ดังนั้นจึงไม่ใช่เชื้อโรค แต่ดูเหมือนว่าเหมาะสมเมื่อได้รับคำตอบ / ความคิดเห็นอื่น ๆ
ps faux |
ใช้งาน อย่ากลัวที่จะยอมรับว่าเครื่องมือ XYZ ไม่เหมาะสมที่สุด
โดยทั่วไป perl จะแทนที่ awk / sed / grep et al., และเป็นมากพกพามากขึ้น (เช่นเดียวกับเป็นเพียงมีดพับที่ดีกว่า)
perl -lane 'print "@F[8..$#F]"'
Timtowtdi ใช้แน่นอน
-l
หรือเพิ่ม\n
ในคำสั่งพิมพ์
awk -v m="\x01" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'
สิ่งนี้จะตัดสิ่งที่อยู่ก่อนฟิลด์ที่กำหนด nr., N และพิมพ์ส่วนที่เหลือทั้งหมดของบรรทัดรวมถึงฟิลด์ nr.N และการรักษาระยะห่างเดิม (จะไม่ฟอร์แมตใหม่) มันจะไม่แปรสภาพหากสตริงของฟิลด์ปรากฏที่อื่นในบรรทัดด้วยซึ่งเป็นปัญหากับคำตอบของ Ascherer
กำหนดฟังก์ชัน:
fromField () {
awk -v m="\x01" -v N="$1" '{$N=m$N; print substr($0,index($0,m)+1)}'
}
และใช้มันดังนี้:
$ echo " bat bi iru lau bost " | fromField 3
iru lau bost
$ echo " bat bi iru lau bost " | fromField 2
bi iru lau bost
เอาต์พุตจะเก็บทุกอย่างรวมถึงช่องว่างต่อท้ายสำหรับ N = 0 จะส่งคืนทั้งบรรทัดตามที่เป็นอยู่และสำหรับ n> NF สตริงว่าง
นี่คือตัวอย่างของls -l
ผลลัพธ์:
-rwxr-----@ 1 ricky.john 1493847943 5610048 Apr 16 14:09 00-Welcome.mp4
-rwxr-----@ 1 ricky.john 1493847943 27862521 Apr 16 14:09 01-Hello World.mp4
-rwxr-----@ 1 ricky.john 1493847943 21262056 Apr 16 14:09 02-Typical Go Directory Structure.mp4
-rwxr-----@ 1 ricky.john 1493847943 10627144 Apr 16 14:09 03-Where to Get Help.mp4
วิธีการแก้ปัญหาของฉันที่จะโพสต์อะไรที่พิมพ์$9
เป็นawk '{print substr($0, 61, 50)}'
ruby -lane 'print $F[3..-1].join(" ")' file
ในการแสดง 3 ฟิลด์แรกและพิมพ์ฟิลด์ที่เหลือคุณสามารถใช้ได้:
awk '{s = ""; for (i=4; i<= NF; i++) s= s $i : "; print $1 $2 $3 s}' filename
โดยที่ $ 1 $ 2 $ 3 คือ 3 ช่องแรก
function print_fields(field_num1, field_num2){
input_line = $0
j = 1;
for (i=field_num1; i <= field_num2; i++){
$(j++) = $(i);
}
NF = field_num2 - field_num1 + 1;
print $0
$0 = input_line
}
การใช้ cut แทน awk และการเอาชนะปัญหาด้วยการหาคอลัมน์ที่จะเริ่มต้นโดยใช้คำสั่ง -c character cut
ที่นี่ฉันกำลังบอกว่าให้ฉันทั้งหมดยกเว้น 49 อักขระแรกของผลลัพธ์
ls -l /some/path/*/* | cut -c 50-
/*/*/
ในตอนท้ายของคำสั่งคำสั่ง ls ไม่ว่าจะเป็นการแสดงฉันสิ่งที่อยู่ในไดเรกทอรีย่อยเกินไป
คุณยังสามารถดึงอักขระบางช่วงออกมาได้อีกด้วย (จากหน้าคนตัด) เช่นแสดงชื่อและเวลาเข้าสู่ระบบของผู้ใช้ที่เข้าสู่ระบบในปัจจุบัน:
who | cut -c 1-16,26-38