ดูไฟล์และพิมพ์ข้อความจากบรรทัดที่ระบุ


8

ฉันมีไฟล์ที่มีข้อมูลที่ฉันบันทึก ตอนนี้ฉันต้องการพิมพ์ผลลัพธ์ของฉันเป็นไฟล์ใหม่

ตัวอย่างเช่นลองทำตัวอย่างนี้randomlog.log:

Link encap:Ethernet HWaddr 08:00:00:00:00:67
inet addr:10.10.10.10 Bcast:10.10.10.10 Mask:255.255.255.0
inet6 addr: fe80::casf:sdfg:23ra:dg12/64 Scope:Link

ฉันจะใช้ข้อมูลจากอักขระที่ 12 ถึง 20 ของบรรทัดแรกเท่านั้นและจากนั้นอักขระที่ 4 ถึง 8 ของบรรทัดที่ 3 ได้อย่างไร ผลลัพธ์จะมีลักษณะดังนี้:

Ethernet
t6 ad

เป็นไปได้ไหม ฉันต้องการตั้งค่าเส้นและจากตำแหน่งเป็นตำแหน่งนี้

คำตอบ:


9

นี่คือsedวิธีการ:

$ sed -nE '1s/.{11}(.{8}).*/\1/p; 3s/.{3}(.{4}).*/\1/p' file  
Ethernet
t6 a

คำอธิบาย

-nไม่ใส่ออกตามปกติ (ปกติคือการพิมพ์เส้นทุกท่าน) เพื่อที่มันจะพิมพ์เมื่อบอกว่าจะ -Eช่วยให้การแสดงออกปกติขยาย

sedสคริปต์มีสองคำสั่งทั้งใช้ประกอบการทดแทน ( s/original/replacement/) 1s/.{11}(.{8}).*/\1/pจะทำงานเฉพาะบนเส้นที่ 1 (ว่าสิ่งที่เป็น1sไม่) และจะตรงกับวันที่ 1 11 ตัวของเส้น ( .{11}) จากนั้นก็จับต่อไป 8 ( (.{8})วงเล็บที่มีกลุ่ม "จับ") และแล้วทุกอย่างอื่นจน จุดสิ้นสุดของบรรทัด ( .*) ทั้งหมดนี้จะถูกแทนที่ด้วยสิ่งที่อยู่ในกลุ่มการจับกุม ( \1; หากมีกลุ่มการจับภาพที่สองมันจะเป็น\2ฯลฯ ) ในที่สุด, pat at end ( s/foo/bar/p) ทำให้เกิดบรรทัดที่จะพิมพ์หลังจากทำการทดแทน ซึ่งส่งผลให้เฉพาะเป้าหมาย 8 ตัวอักษรที่ถูกส่งออก

คำสั่งที่สองเป็นแนวคิดทั่วไปเดียวกันยกเว้นว่ามันจะทำงานเฉพาะในบรรทัดที่ 3 ( 3s) และจะเก็บอักขระ 4 ตัวที่เริ่มต้นจาก 4


คุณสามารถทำสิ่งเดียวกันกับperl:

$ perl -ne 'if($.==1){s/.{11}(.{8}).*/\1/}
            elsif($.==3){s/.{3}(.{4}).*/\1/}
            else{next}; print; ' file 
Ethernet
t6 a

คำอธิบาย

-neหมายถึง "อ่านบรรทัดแฟ้มใส่โดยสายและใช้สคริปต์ที่กำหนดโดย-eแต่ละบรรทัด. สคริปต์ที่เป็นพื้นฐานความคิดเช่นเดียวกับก่อน. the $.ตัวแปรถือหมายเลขบรรทัดปัจจุบันเพื่อให้เราตรวจสอบว่าหมายเลขบรรทัดเป็นอย่างใดอย่างหนึ่ง1หรือ3ไม่และหาก ดังนั้นให้รันการทดแทนมิฉะนั้นจะข้ามดังนั้นprintจะรันเฉพาะสำหรับสองบรรทัดเหล่านั้นเท่านั้นเนื่องจากการข้ามทั้งหมดจะถูกข้าม


แน่นอนว่านี่คือ Perl ดังนั้นTIMTOWTDI :

$ perl -F"" -lane '$. == 1 && print @F[11..19]; $.==3 && print @F[3..6]' file 
Ethernet 
t6 a

คำอธิบาย

ที่นี่-aหมายถึง "แยกแต่ละบรรทัดอินพุตบนตัวละครที่กำหนดโดย-Fและบันทึกเป็นอาร์เรย์@Fเนื่องจากตัวละครที่กำหนดว่างเปล่านี้จะบันทึกตัวละครของแต่ละบรรทัดอินพุตเป็นองค์ประกอบ@Fมาแล้วเราพิมพ์องค์ประกอบ 11-19 ( อาร์เรย์เริ่มนับที่0) สำหรับบรรทัดที่ 1 และ 3-7 สำหรับที่ 3


1

วิธี awk:

$ awk 'NR==1{print substr($0,12,8)};NR==3{print substr($0,4,4)}' input.txt  
Ethernet
t6 a

ใช้NRสำหรับพิจารณาจำนวนบรรทัด (ใน awk คำศัพท์ - บันทึก) และพิมพ์สตริงย่อยของบรรทัด substr()ฟังก์ชั่นอยู่ในรูปแบบ

substr(string,starting position,how much offset) 

หลาม

$ python -c 'import sys                                                                                                                                                
> for index,line in enumerate(sys.stdin,1):                                                                                                                            
>     if index == 1:
>          print line[11:19]
>     if index == 3:
>          print line[3:7]' < input.txt
Ethernet
t6 a

สิ่งนี้ใช้<ตัวดำเนินการเชลล์เพื่อเปลี่ยนเส้นทางสตรีมอินพุตไปยังกระบวนการไพ ธ อนจากไฟล์อินพุต โปรดทราบว่าสตริงใน python นั้นมีการจัดทำดัชนี 0 ดังนั้นคุณต้องเปลี่ยนหมายเลขอักขระที่คุณต้องการทั้งหมดทีละ 1

เปลือกแบบพกพา

งานนี้ในksh, ,dash bashอาศัยเฉพาะยูทิลิตี้ของเชลล์เท่านั้นไม่มีอะไรภายนอก

#!/bin/sh

rsubstr(){
    i=0;
    while [ $i -lt  $2 ];
    do
        rmcount="${rmcount}?"
        i=$(($i+1))
    done;
    echo "${1#$rmcount}"
}

lsubstr(){
    printf "%.${2}s\n" "$1"
}

line_handler(){
    case $2 in
        1) lsubstr "$(rsubstr "$1" 11)" 8 ;;
        3) lsubstr "$(rsubstr "$1" 3)" 5 ;;
    esac
}

readlines(){
    line_count=1
    while IFS= read -r line;
    do
        line_handler "$line" "$line_count"
        line_count=$(($line_count+1))
    done < $1
}

readlines "$1"

และมันก็ทำงานได้เช่น:

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