之后抓取一个单词和可变数量的字符

时间:2019-01-29 16:35:35

标签: regex string text awk sed

我有一个包含长字符串的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(*/-|\;)

expected-output.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 :(得分:1)

请您尝试以下。

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.

答案 1 :(得分:1)

对于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()捕获的内容。

检查Regular expression,了解更多信息。

答案 2 :(得分:1)

尝试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|

$

答案 3 :(得分:1)

这可能对您有用(GNU sed):

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

在行的第八个字段前添加换行符,并在第二个替换中将其用作标记。删除要保留的匹配字符串前后的标记和字符。如果第二个匹配失败,请删除换行符。

答案 4 :(得分:0)

尝试使用sed -r扩展正则表达式:

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

它通过提取您想要保留的东西来进行清洁。不过,它并不特定于第八栏。