テキストと数字の組み合わせを含むタブ区切りのファイルがあります。各行はそのまま維持したいのですが、5番目の列には6桁の数字しか存在しない場合はそのまま維持したいと思います。たとえば、
gene1 NM_033629 598G>A P912 syndrome 1, 192315 syndrome 2, 225750 syndrome 3 610448 score AD hom user 123456 Source
gene2 NM_000459 613G>A V115I syndrome 1 600195 score AD rec user 234567 Source
(症候群#は例として使用されており、任意のテキストである可能性があるため、検索して削除できるパターンではありません。)
私は出力が次のようになります:
gene1 NM_033629 598G>A P912 192315 225750 610448 score AD hom user 123456 Source
gene2 NM_000459 613G>A V115I 600195 score AD rec user 234567 Source
6桁の数字を抽出する方法は4つありますが、それはできません。
ㅏ。元の行の数字を出力します。
b。編集されたフィールドを含む行全体を正常に印刷します。数値の抽出に使用するオプションは次のとおりです。
cat inputfile | cut -f 5 |grep -P '(? < !\d)\d{6}(?!\d)'
cat inputfile | cut -f 5 |grep -Po '(?< !\d)\d{6}(?!\d)'
cat inputfile | cut -f 5 |grep -o '[[:digit:]]*'
cat inputfile | cut -f 5 |grep -o "[0-9]\{6\}"
列にカットを使用するのが正しくないことを知っていますが、フィールド9にも6桁の数字があるので、抽出が正しいことを確認したいと思います。私はそれをすべて一緒に保つと主張します。どんな提案でもよろしくお願いします。
答え1
私が正しく理解したら、5番目の列はその中の6桁の数字をすべて空白で連結したいと思います。
おそらく:
perl -F'\t' -lape '
$F[4] = join " ", grep {length == 6} ($F[4] =~ /\d+/g);
$_ = join "\t", @F' < file
または、オペレーターに対する否定的なコメントを再利用してください。
perl -F'\t' -lape '
$F[4] = join " ", ($F[4] =~ /(?<!\d)\d{6}(?!\d)/g);
$_ = join "\t", @F' < file
そしてawk
:
awk -F'\t' -v OFS='\t' '
{
repl = sep = ""
while (match($5, /[0-9]+/)) {
if (RLENGTH == 6) {
repl = repl sep substr($5, RSTART, RLENGTH)
sep = " "
}
$5 = substr($5, RSTART+RLENGTH)
}
$5 = repl
print
}' < file
grep
それ自体は仕事には十分ではありません。grep
パターンに一致する線を印刷するように設計されています。 GNU や ast-open などの一部の実装では、一致する行から文字列を抽出できますが、grep
これpcregrep
は非常に制限的です。
特定の制限で機能できると考えられる唯一の++アプローチは、次のことを実装することcut
です。grep
paste
pcregrep
grep
n='(?:.*?((?1)))?'
paste <(< file cut -f1-4) <(< file cut -f5 |
pcregrep --om-separator=" " -o1 -o2 -o3 -o4 -o5 -o6 -o7 -o8 -o9 \
"((?<!\d)\d{6}(?!\d))$n$n$n$n$n$n$n$n"
) <(< file cut -f6-)
各入力行には少なくとも6つのフィールドがあり、各フィールドの5番目のフィールドには1から9の6桁の数字があるとします。
答え2
awk '
BEGIN {
FS = "\t";
OFS = "\t";
}
{
cnt = patsplit($5, arr, /[0-9]{6}/);
$5 = arr[1];
for(i = 2; i <= cnt; i++) {
$5 = $5 " " arr[i];
}
print;
}' input.txt
patsplit(s, a [, r [, seps] ])- 分割文字列 S配列としてㅏと区切り文字の配列9月正規表現についてアル字型、フィールド数を返します。 要素値は r と一致する s の一部です。。
入力する:
gene1 NM_033629 598G>A P912 syndrome 1, 192315 syndrome 2, 225750 syndrome 3 610448 score AD hom user 123456 Source
gene2 NM_000459 613G>A V115I syndrome 1 600195 score AD rec user 234567 Source
出力:
gene1 NM_033629 598G>A P912 192315 225750 610448 score AD hom user 123456 Source
gene2 NM_000459 613G>A V115I 600195 score AD rec user 234567 Source