我的文本文件看起来像这样
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
答案 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
如果您的短语包含数字,请尝试使用此perl正则表达式:'[^;]+?(?=\s+\d+(;|$))'
答案 3 :(得分:1)
只有awk:
$ 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