使用不同的分隔符提取文本

时间:2013-02-27 00:18:09

标签: perl unix text-files delimiter

我的文本文件看起来像这样

foo.en 14 :: xyz 1;foo bar 2;foofoo 5;bar 9
bar.es 18 :: foo bar 4;kjp bar 2;bar 6;barbar 8

忽略::分隔符之前的文本,是否有一个单行程序unix命令(允许多个管道)或一个字符串perl脚本提取文本,以便生成由{{分隔的唯一单词的输出1}}?

;

我已经尝试使用python脚本循环遍历文本文件,但我正在为该任务寻找一个单行程序。

xyz
foo bar
foofoo
bar
kjp bar
barbar

4 个答案:

答案 0 :(得分:3)

使用Perl:

perl -nle 's/.*?::\s*//;!$s{$_}++ and print for split /\s*\d+;?/' input

<强>描述

s/.*?::\s*//;  # delete up to the first '::'

这部分:

!$s{$_}++ and print for split /\s*\d+;?/

可以像这样重写:

foreach my $word (split /\s*\d+;?/) {   # for split /\s*\d+;?/
  if (not defined $seen{$word}}) {      # !$s{$_}
    print $word;                        # and print
  }
  $seen{$word}++;                       # $s{$_}++
}

由于!$s{$_}++中的增量是后增量,Perl首先测试错误条件,然后进行增量。未定义的哈希值的值为0。如果测试失败,即$s{$_}先前已递增,则由于short circuiting而跳过部分。

答案 1 :(得分:2)

cat textfile | sed 's/.*:://g' |  tr '[0-9]*;' '\n' | sort -u

说明:

sed 's/.*:://g'      Take everything up to and including `::` and replace it with nothing
tr '[0-9];' '\n'     Replace numbers and semicolon with newlines
sort -u              Sort, and return unique instances

它确实会导致排序输出,我相信......

答案 2 :(得分:1)

你可以试试这个:

$ awk -F ' :: ' '{print $2}' input.txt | grep -oP '[^0-9;]+' | sort -u
bar 
barbar 
foo bar 
foofoo 
kjp bar 
xyz 

如果您的短语包含数字,请尝试使用此正则表达式:'[^;]+?(?=\s+\d+(;|$))'

答案 3 :(得分:1)

只有

$ awk -F' :: ' '{
    gsub(/[0-9]+/, "")
    split($2, arr, /;/ )
    for (a in arr) arr2[arr[a]]=""
}
END{
    for (i in arr2) print i
}' textfile.txt

一个单行版本:

 awk -F' :: ' '{gsub(/[0-9]+/, "");split($2, arr, /;/ );for (a in arr) arr2[arr[a]]="";}END{for (i in arr2) print i}' textfile.txt