一致するパターンを編集してから、他のパターンを編集したパターンに置き換える方法はありますか?
入力する:
a11.t
some text here
a06.t
some text here
出力:
a11.t 11
some text here
a06.t 06
some text here
上記の例では、抽出された最初の2つの数字(最初のパターンと一致)を示し、行の末尾に配置します(2番目のパターン)。
プログラミング言語では、ファイルをデータ構造にロード、編集、置換、および新しいファイルを作成しました。しかし、それに対応する1行のコードはありますか?
裁判:
sed 's/\(a[0-9][0-9].*\)/& \1/I' stack.fa | sed -e 's#a##g2' -e 's#\.\w##g2'
テスト出力:
a11.t 11
some text here
a06.t 06
some text here
明らかに実験は効果がありますが、より強力なアプローチはありますか?また、これをより簡単に実行できる別のテキスト処理言語がありますか?
答え1
年齢にもかかわらず、テキスト処理の面でPerlと競合する言語はほとんどありません。たとえば、
行の末尾にコピーされた数値セットのみがあるとします。
$ perl -pe 's/.*?a(\d+).*/$& $1/' file a11.t 11 some text here a06.t 06 some text here
複数の数値セット、最後に2つを追加します。
$ cat file a11.t some text here a06.t some text here a11.t a54.g $ perl -pe '@nums=(/a(\d+)/g); s/$/ @nums/' file a11.t 11 some text here a06.t 06 some text here a11.t a54.g 11 54
答え2
sed
これは仕事に最適なツールです。ただし、スクリプトは複数のコマンドで構成できるため、複数の呼び出しsed
をまとめて接続する必要はほとんどありません。sed
10進数の2桁の最初のシーケンスを抽出して検索し、行の末尾にスペースを追加するには、次のようにします。
sed 's/\([[:digit:]]\{2\}\).*$/& \1/' < your-file
行の2番目の場所でそれを見つけて、次のような場合にのみこれを実行したい場合a
:
sed 's/^a\([[:digit:]]\{2\}\).*$/& \1/' < your-file
これをしたくない場合は、2桁のシーケンスの後に数字が続きます。
sed 's/^a\([[:digit:]]\{2\}\)\([^[:digit:]].*\)\{0,1\}$/& \1/' < your-file
~によると堅牢性この質問に対する答えは次のとおりです。何と対にする必要がありますか?そしてそれではいけないことは何ですか?。そのため、要件を明確に指定し、入力がどのように表示されるかを理解することが重要です(例:一致するものを探したくない数字は行にありますか?、入力にASCII以外の文字を含めることはできますか?、入力はロケールの文字セットでエンコードされていますか?など。 )。
上記の実装では、入力はsed
ロケールの文字マップ(の出力を参照locale charmap
)に従ってテキストとしてデコードされるか、文字に対応する各バイトとして解釈され、バイト0〜127はASCII文字マップ(EBCDICベースのシステムではないと仮定します)。
最初の実装タイプでは、sed
ファイルが正しい文字セットにエンコードされていないと正しく機能しない可能性があります。 2番目のカテゴリの場合、入力に10進エンコーディングを含む文字が含まれていると失敗する可能性があります。
答え3
最も簡単な方法は次のとおりです。
$ perl -lne '$,=$"; print $_, /a(\d+)/' file
# or this
$ perl -lpe 's/a(\d+).*\K/ $1/' file
$ awk '
match($1, /^a[[:digit:]]+/) &&
gsub(/$/, FS substr($1, RSTART+1, RLENGTH-1)) ||
1' file
substr
注:交換セクションgsub
は純粋な数字のみで構成されているため、安全に使用できます。
答え4
perl
または、行くことができますが、完成のためにモジュールの一致するsed
「グループ」の概念を使用して@PraveenKumarBSのPythonフラグメントの最初のバージョンを書き換えます。re
#!/usr/bin/python3
import re
pattern = re.compile(r'(\d{2})')
with open('data', 'r') as file:
for line in file:
match = re.search(pattern, line)
if match:
print(line.rstrip('\n'), match.group(1))
else:
print(line.rstrip('\n'))
OPが探しているパターンに常に最初の文字が含まれていることを示唆していると思われる場合は、パターンを次のように設定してくださいpattern = re.compile(r'[a-zA-Z](\d{2})')
。
match = re.finditer(pattern, line)
1行に複数の一致がある角度(?)の場合は、新しい一致式と修正されたディレクティブ(@terdonが述べたように)を使用して簡単に処理できますprint
。