Захватить слово и переменное количество символов впоследствии - PullRequest
0 голосов
/ 29 января 2019

У меня есть TAB отдельный файл, содержащий длинные строки, который я собираюсь отфильтровать в 8th column, который содержит произвольную комбинацию букв и символов, и содержащую только часть ";OCCURRENCE=some words|", как показано ниже:

input.txt

1 138440 CAMEL C T . . MANY-WORDS-AND-CHARACTERS(*/-;|\);OCCURRENCE=HOY-BR|MANY-WORDS-AnD-CHARACTeRS(;*/-|\)
1 138440 CAT CD TGGD . . MANY-WORDS-AND-CHARACTERS(;*/-|\);OCCURRENCE=DISC-BF5R|MANY-WORDS-AnD-CHARACTeRS(*/-|\;)

Ожидаемый-выход.txt:

1 138440 CAMEL C T . . ;OCCURRENCE=HOY-BR|
1 138440 CAT CD TGGD . . ;OCCURRENCE=DISC-BF5R|

Я пытался "очистить" 8th column до тех пор, пока в полуколонне со строкой OCCUR не отобразитсяс sed 's/.*;OCCUR//g', но он стирает другие столбцы, поэтому он не работает.

Как сохранить шаблон ;OCCURANCE=whatever-word| в 8-м столбце, не стирая другие столбцы?

Ответы [ 5 ]

0 голосов
/ 30 января 2019

Это может работать для вас (GNU sed):

sed -E 's/\S+/\n&/8;s/\n.*(;OCCURRENCE=[^|]*\|).*/\1/;s/\n//' file

Подставить новую строку к восьмому полю строки и использовать ее во второй замене в качестве маркера.Удалите маркер и символы до и после соответствующей строки, которая будет сохранена.Удалите новую строку, если второе совпадение не будет успешным.

0 голосов
/ 29 января 2019

Попробуйте Perl

perl -lne ' while(/(\S+)/g) { $x++; if ($x==8) { $y=$1; @y=split(/;|\|/,$y); $z=quotemeta($y); s/$z/;$y[3]|/g;  } } ; print;  $x=0 '

, используя входы

$ cat bapors.txt
1 138440 CAMEL C T . . MANY-WORDS-AND-CHARACTERS(*/-;|\);OCCURRENCE=HOY-BR|MANY-WORDS-AnD-CHARACTeRS(;*/-|\)
1 138440 CAT CD TGGD . . MANY-WORDS-AND-CHARACTERS(;*/-|\);OCCURRENCE=DISC-BF5R|MANY-WORDS-AnD-CHARACTeRS(*/-|\;)

$ perl -lne ' while(/(\S+)/g) { $x++; if ($x==8) { $y=$1; @y=split(/;|\|/,$y); $z=quotemeta($y); s/$z/;$y[3]|/g;  } } ; print;  $x=0 ' bapors.txt
1 138440 CAMEL C T . . ;OCCURRENCE=HOY-BR|
1 138440 CAT CD TGGD . . ;OCCURRENCE=DISC-BF5R|

$
0 голосов
/ 29 января 2019

Попробуйте, sed -r для расширенных регулярных выражений:

sed -r 's/ \S+(;OCCUR[^|]+\|)\S+/ \1/g'

Он очищает, извлекая то, что вы хотите сохранить.Это не относится к 8-му столбцу.

0 голосов
/ 29 января 2019

Для GNU sed, а точнее:

$ sed -E 's/((\S+\s){7}).*(\;OCCURRENCE=[^\|]*\|).*/\1\3/' input.txt
1 138440 CAMEL C T . . ;OCCURRENCE=HOY-BR|
1 138440 CAT CD TGGD . . ;OCCURRENCE=DISC-BF5R|

Поэтому, независимо от того, разделен ли он TAB или пробелами, отфильтруйте 8-й столбец в соответствии с вашим описанием.

\Sозначает символ без пробела.
\s означает символ пробела.
+ означает, что символ / группа появляются один или несколько раз.
{7} означает, что символ / группа появляются 7 раз.
[^\|] означает любой символ, который не является |.
\num означает num th () перехваченное содержимое.

Проверка Регулярное выражение длябольше.

0 голосов
/ 29 января 2019

Не могли бы вы попробовать следующее.

awk 'match($NF,/\;[a-zA-Z]+[^|]*/){$NF=substr($NF,RSTART,RLENGTH+1)} 1' Input_file

Объяснение: Добавление пояснения к приведенному выше коду здесь.

awk '                                   ##Starting awk program here.
match($NF,/\;[a-zA-Z]+[^|]*/){          ##Using match function here to match a REGEX in $NF(last field of line).
  $NF=substr($NF,RSTART,RLENGTH+1)      ##Re-assigning last field and keeping its value as substring values of RSTART and RLENGTH
}                                       ##Where RSTART and RLENGTH variables will be SET when a match is found within match REGEX, refer man awk for more details too.
1                                       ##Mentioning 1 will print edited/non-edited current line.
'  Input_file                           ##Mentioning Input_file name here.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...