ファイルを調べ、特定の行からテキストを印刷する


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

1行目の12〜20文字目から、3行目の4〜8文字目のデータのみを取得するにはどうすればよいですか。出力は次のようになります。

Ethernet
t6 ad

これは可能ですか?線と位置からこの位置に設定したい。

回答:


9

ここにsedアプローチがあります:

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

説明

-n通常の出力を抑制し(通常はすべての入力行を印刷します)、指示された場合にのみ印刷します。-E拡張正規表現を可能にします。

sedこのスクリプトは、(両方の置換演算子を使用して、2つのコマンドを持っていますs/original/replacement/)。1s/.{11}(.{8}).*/\1/pのみ(何番目のライン上で実行されます1sし)、及びラインの第一11文字と一致します(.{11})、それはキャプチャ次の8を((.{8})するまで、括弧は「キャプチャグループ」です)、その後、他のすべて行の終わり(.*)。これはすべて、キャプチャグループ内にあったものに置き換えられ\1ます(; 2番目のキャプチャグループがあった場合、それは\2など)。最後に、p最後の(s/foo/bar/p)は、置換が行われた後に行を印刷します。これにより、ターゲットの8文字のみが出力されます。

2番目のコマンドは、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各行にする。スクリプトは以前と同じ基本的な考え方である。$.我々は、行番号がどちらかであるかどうかを確認して、変数が現在の行番号を保持している1か、3場合、およびしたがって、置換を実行し、そうでprintない場合はスキップします。したがって、他のすべての行がスキップされるため、これらの2行に対してのみが実行されます。


もちろん、これは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行目では3〜7です。


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プロセスにリダイレクトします。Pythonの文字列には0インデックスが付いているため、目的の文字数をすべて1だけシフトする必要があることに注意してください。

ポータブルシェルウェイ

これはで動作しkshdashbash。シェルユーティリティのみに依存し、外部には依存しません。

#!/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.