ฉันกำลังพยายามลบสองคอลัมน์แรก (ซึ่งฉันไม่สนใจ) ออกจากไฟล์บันทึก DbgView ดูเหมือนจะไม่พบตัวอย่างที่พิมพ์ตั้งแต่คอลัมน์ 3 เป็นต้นไปจนถึงท้ายบรรทัด โปรดทราบว่าแต่ละบรรทัดมีจำนวนคอลัมน์ที่แปรผัน
ฉันกำลังพยายามลบสองคอลัมน์แรก (ซึ่งฉันไม่สนใจ) ออกจากไฟล์บันทึก DbgView ดูเหมือนจะไม่พบตัวอย่างที่พิมพ์ตั้งแต่คอลัมน์ 3 เป็นต้นไปจนถึงท้ายบรรทัด โปรดทราบว่าแต่ละบรรทัดมีจำนวนคอลัมน์ที่แปรผัน
คำตอบ:
... หรือวิธีแก้ปัญหาที่ง่ายกว่านั้น: cut -f 3- INPUTFILE
เพียงแค่เพิ่มตัวคั่นที่ถูกต้อง (-d) และคุณจะได้รับเอฟเฟกต์เดียวกัน
awk '{for(i=3;i<=NF;++i)print $i}'
awk '{for(i=3;i<=NF;++i)printf $i""FS ; print ""}'
( printf
จะไม่พิมพ์อักขระขึ้นบรรทัดใหม่ในขณะที่print ""
จะเพิ่มบรรทัดใหม่หลังจากพิมพ์ฟิลด์อื่นแล้ว)
echo $(seq 1 10) | awk '{for (i=3; i<=NF; i++) printf $i FS}'
ซึ่งให้: 3 4 5 6 7 8 9 10
.
awk '{ print substr($0, index($0,$3)) }'
พบวิธีแก้ปัญหาที่นี่:
http://www.linuxquestions.org/questions/linux-newbie-8/awk-print-field-to-end-and-character-count-179078/
คำตอบของJonathan Feinbergจะพิมพ์แต่ละฟิลด์ในบรรทัดแยกกัน คุณสามารถใช้printf
เพื่อสร้างเรกคอร์ดใหม่สำหรับเอาต์พุตในบรรทัดเดียวกัน แต่คุณสามารถย้ายฟิลด์ข้ามไปทางซ้ายได้
awk '{for (i=1; i<=NF-2; i++) $i = $(i+2); NF-=2; print}' logfile
NF
POSIX ไม่อนุญาตให้ลดค่าใช้จ่าย
NF
สามารถลดลงได้หรือไม่
awk '{$1=$2=$3=""}1' file
หมายเหตุ: วิธีนี้จะปล่อย "ช่องว่าง" ไว้ในช่อง 1,2,3 แต่ไม่ใช่ปัญหาหากคุณต้องการดูผลลัพธ์
1
หมายถึงอะไร? ฉันควรค้นหาด้วยคำหลักawk
ใด
{$1=$2=$3="";$0=$0;$1=$1}1
หากคุณต้องการพิมพ์คอลัมน์หลังจากที่ 3 เช่นในบรรทัดเดียวกันคุณสามารถใช้:
awk '{for(i=3; i<=NF; ++i) printf "%s ", $i; print ""}'
ตัวอย่างเช่น:
Mar 09:39 20180301_123131.jpg
Mar 13:28 20180301_124304.jpg
Mar 13:35 20180301_124358.jpg
Feb 09:45 Cisco_WebEx_Add-On.dmg
Feb 12:49 Docker.dmg
Feb 09:04 Grammarly.dmg
Feb 09:20 Payslip 10459 %2828-02-2018%29.pdf
มันจะพิมพ์:
20180301_123131.jpg
20180301_124304.jpg
20180301_124358.jpg
Cisco_WebEx_Add-On.dmg
Docker.dmg
Grammarly.dmg
Payslip 10459 %2828-02-2018%29.pdf
อย่างที่เราเห็นสลิปเงินเดือนแม้จะมีช่องว่างก็แสดงในบรรทัดที่ถูกต้อง
สิ่งที่เกี่ยวกับบรรทัดต่อไปนี้:
awk '{$ 1 = $ 2 = $ 3 = ""; print} 'ไฟล์
ตามคำแนะนำของ @ ghostdog74 ของฉันควรทำงานได้ดีขึ้นเมื่อคุณกรองบรรทัดกล่าวคือ:
awk '/ ^ exim4-config / {$ 1 = ""; print} 'ไฟล์
sed 's/\s\+//g'
awk -v m="\x0a" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'
สิ่งนี้จะตัดสิ่งที่อยู่ก่อนฟิลด์ที่กำหนด nr., N และพิมพ์ส่วนที่เหลือทั้งหมดของบรรทัดรวมถึงฟิลด์ nr.N และการรักษาระยะห่างเดิม (จะไม่ฟอร์แมตใหม่) มันจะไม่แปรสภาพถ้าสตริงของฟิลด์ปรากฏที่อื่นในบรรทัดด้วยซึ่งเป็นปัญหากับคำตอบของ daisaa
กำหนดฟังก์ชัน:
fromField () {
awk -v m="\x0a" -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' เป็นตัวคั่นบันทึกดังนั้นคุณจึงไม่มีอักขระขึ้นบรรทัดใหม่ภายในบรรทัด หากคุณต้องการใช้ร่วมกับตัวคั่นบันทึกอื่น ๆ ให้ใช้:
awk -v m="\x01" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'
ตัวอย่างเช่น. ทำงานได้ดีกับไฟล์เกือบทั้งหมดตราบเท่าที่ไม่ได้ใช้เลขฐานสิบหกถ่าน nr 1 ภายในเส้น
คำสั่ง awk ต่อไปนี้จะพิมพ์ฟิลด์ N สุดท้ายของแต่ละบรรทัดและในตอนท้ายของบรรทัดจะพิมพ์อักขระบรรทัดใหม่:
awk '{for( i=6; i<=NF; i++ ){printf( "%s ", $i )}; printf( "\n"); }'
ค้นหาด้านล่างตัวอย่างที่แสดงรายการเนื้อหาของไดเร็กทอรี / usr / bin จากนั้นเก็บ 3 บรรทัดสุดท้ายจากนั้นพิมพ์ 4 คอลัมน์สุดท้ายของแต่ละบรรทัดโดยใช้ awk:
$ ls -ltr /usr/bin/ | tail -3
-rwxr-xr-x 1 root root 14736 Jan 14 2014 bcomps
-rwxr-xr-x 1 root root 10480 Jan 14 2014 acyclic
-rwxr-xr-x 1 root root 35868448 May 22 2014 skype
$ ls -ltr /usr/bin/ | tail -3 | awk '{for( i=6; i<=NF; i++ ){printf( "%s ", $i )}; printf( "\n"); }'
Jan 14 2014 bcomps
Jan 14 2014 acyclic
May 22 2014 skype
awk '{a=match($0, $3); print substr($0,a)}'
อันดับแรกคุณจะพบตำแหน่งของจุดเริ่มต้นของคอลัมน์ที่สาม ด้วย Substr คุณจะพิมพ์ทั้งบรรทัด ($ 0) โดยเริ่มจากตำแหน่ง (ในกรณีนี้ a) ไปยังจุดสิ้นสุดของบรรทัด
คุณสามารถทำเอฟเฟกต์เดียวกันได้อย่างง่ายดายโดยใช้นิพจน์ทั่วไป สมมติว่าตัวคั่นเป็นช่องว่างมันจะมีลักษณะดังนี้:
awk '{ sub(/[^ ]+ +[^ ]+ +/, ""); print }'
awk '{ sub(/([^ ]+ +){2}/, ""); print }'
ซึ่งจะใช้รูปแบบห่างออกไปสองเท่า
awk '{print ""}{for(i=3;i<=NF;++i)printf $i" "}'
โซลูชัน Perl:
perl -lane 'splice @F,0,2; print join " ",@F' file
ใช้ตัวเลือกบรรทัดคำสั่งเหล่านี้:
-n
วนรอบทุกบรรทัดของไฟล์อินพุตอย่าพิมพ์ทุกบรรทัดโดยอัตโนมัติ
-l
ลบบรรทัดใหม่ก่อนประมวลผลและเพิ่มกลับเข้าไปในภายหลัง
-a
โหมด autosplit - แยกบรรทัดอินพุตลงในอาร์เรย์ @F ค่าเริ่มต้นคือการแบ่งช่องว่าง
-e
ดำเนินการรหัส perl
splice @F,0,2
ลบคอลัมน์ 0 และ 1 ออกจากอาร์เรย์ @F อย่างหมดจด
join " ",@F
รวมองค์ประกอบของอาร์เรย์ @F โดยใช้ช่องว่างระหว่างแต่ละองค์ประกอบ
หากไฟล์อินพุตของคุณคั่นด้วยจุลภาคแทนที่จะใช้การคั่นด้วยช่องว่างให้ใช้ -F, -lane
โซลูชัน Python:
python -c "import sys;[sys.stdout.write(' '.join(line.split()[2:]) + '\n') for line in sys.stdin]" < file
ที่นี่สายไปหน่อย แต่ดูเหมือนจะไม่ได้ผล ลองใช้วิธีนี้โดยใช้ printf แทรกช่องว่างระหว่างแต่ละอัน ฉันเลือกที่จะไม่ขึ้นบรรทัดใหม่ในตอนท้าย
awk '{for(i=3;i<=NF;++i) printf("%s ", $i) }'
awk '{for (i=4; i<=NF; i++)printf("%c", $i); printf("\n");}'
พิมพ์บันทึกโดยเริ่มจากฟิลด์ที่ 4 ไปยังฟิลด์สุดท้ายตามลำดับเดียวกันกับที่อยู่ในไฟล์ต้นฉบับ
ใน Bash คุณสามารถใช้ไวยากรณ์ต่อไปนี้กับพารามิเตอร์ตำแหน่ง:
while read -a cols; do echo ${cols[@]:2}; done < file.txt
เรียนรู้เพิ่มเติม: การจัดการพารามิเตอร์ตำแหน่งที่ Bash Hackers Wiki
หากเป็นเพียงการละเว้นสองฟิลด์แรกและหากคุณไม่ต้องการช่องว่างเมื่อกำบังฟิลด์เหล่านั้น (เช่นเดียวกับคำตอบด้านบนบางคำ):
awk '{gsub($1" "$2" ",""); print;}' file
awk '{$1=$2=""}1' FILENAME | sed 's/\s\+//g'
สองคอลัมน์แรกถูกล้างsed
เอาช่องว่างนำหน้าออก
ในคอลัมน์ AWK เรียกว่าฟิลด์ดังนั้น NF จึงเป็นกุญแจสำคัญ
ทุกแถว:
awk -F '<column separator>' '{print $(NF-2)}' <filename>
แถวแรกเท่านั้น:
awk -F '<column separator>' 'NR<=1{print $(NF-2)}' <filename>