2010-11-30 78 views
14

sedマニュアルでは、代用品の置換文字列で利用可能な後方参照が\ 1〜\ 9の番号を持つことが明確に記載されています。私は10フィールドを持つログファイルを解析しようとしています。sed後方参照制限を回避する 1〜 9

私はそれのために形成された正規表現を持っていますが、10番目の試合(と後のもの)はアクセスできません。

KSH(またはおそらく私がシェルスクリプトに移植できる言語)でこの制限を回避するには誰も優雅な方法がありますか?

+2

あなたはかなりあなたは、このためのワンライナーを書くことができます任意のスクリプト言語を使用することができます。 'perl -pe 's/yourregexhere/$ 1 $ 2 $ 3 $ 4 $ 5 $ 6 $ 7 $ 8 $ 9 $ 10 /'' –

+0

多くの後方参照を必要としないより簡単な正規表現を使うことができるかもしれません。いくつかのサンプルデータと必要な出力の例を表示すると、もっと簡単な方法を示しているかもしれません。 –

+1

は 'awk'の仕事のように聞こえます - フィールド10は' $ 10'です –

答えて

13

sedの代わりにperl -pe 's/(match)(str)/$2$1/g;'ユーザーを使用できますか?逆参照制限を回避する方法は、sed以外のものを使用することです。

また、2段階で置換を行うことができますが、あなたのパターンはわからないので、どうやって手助けすることはできません。

+0

ありがとうございました。今すぐパターンを生成してkshスクリプトからこのコマンドを実行する方法を理解する必要がありますが、それは別の日の質問です。 –

3

あなたはシェルスクリプトソリューションを求めています。つまり、あなたはsedのみを使用することに限定されません。ほとんどのシェルは配列をサポートしているので、おそらくあなたはその行をシェル配列変数に解析できますか?必要であれば、同じ行を複数回解析して、各パスで異なるビットの情報を抽出することもできます。

そうでしょうか?

1

正規表現の逆参照の使用を必要としないソリューションを考えてみましょう。たとえば、単純なフィールド区切り文字がある場合は、splitを使用するか、perlではなくawkを使用して処理します。

3

置換された要素が分割されたグループ内にある限り、ストリームを-eで分割します。私は日付を分割して、日付 ​​- 時間を14桁の文字列に再編成することができました。ストリームを3回上に分割しなければなりませんでした。

echo "created: 02/05/2013 16:14:49" | sed -e 's/^\([[:alpha:]]*: \)//' -e 's/\([0-9]\{2\}\)\(\/\)\([0-9]\{2\}\)\(\/\)\([0-9]\{4\}\)\(\)/\5\1\3/' -e 's/\([0-9]\{2\}\)\(\:\)\([0-9]\{2\}\)\(\:\)\([0-9]\{2\}\)/\1\3\5/' 
0

あなたはGNU awkを持っている場合、あなたはコントロールで、はるかに物事を行うことができます。このためには、match(source,/regex/,array)構成が必要です。

例:テスト用

サンプル入力:

echo "$x" 
p1=aaa,p2=bb,p3=cc,p4=dd,p5=ee,p6=ff,p7=gg,p8=hh,p9=ii,p10=jj 

sed\9まで正常に動作:\10が追加されたとき

echo $x |sed -r 's/p1=([^,]+).*p2=([^,]+).*p3=([^,]+).*p4=([^,]+).*p5=([^,]+).*p6=([^,]+).*p7=([^,]+).*p8=([^,]+).*p9=([^,]+)(.*)/\1 \2 \3 \4 \5 \6 \7 \8 \9/' 
aaa bb cc dd ee ff gg hh ii 

sedが壊れ、それが\1 + 0であると考えられます。

echo $x |sed -r 's/p1=([^,]+).*p2=([^,]+).*p3=([^,]+).*p4=([^,]+).*p5=([^,]+).*p6=([^,]+).*p7=([^,]+).*p8=([^,]+).*p9=([^,]+).*p10=([^,]+)(.*)/\1 \2 \3 \4 \5 \6 \7 \8 \9 \10/' 
aaa bb cc dd ee ff gg hh ii aaa0 

awkバックリファレンスが9個以上追加された場合に救助する。ここでは第十refrenceが追加されます:

echo "$x" |awk '{match($0,/p1=([^,]+).*p2=([^,]+).*p3=([^,]+).*p4=([^,]+).*p5=([^,]+).*p6=([^,]+).*p7=([^,]+).*p8=([^,]+).*p9=([^,]+).*p10=([^,]+)(.*)/,a);print a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10]}' 
aaa bb cc dd ee ff gg hh ii jj 
関連する問題