要在文件中使用“UNIQUE:”作为前缀的唯一单词,我尝试使用perl regex命令,如:
perl -e 'undef $/;while($_=<>){s/^(((?!\b\3\b).)*)\b(\w+)\b(((?!\b\3\b).)*)$/\1UNIQUE:\3\4/gs;print $_;}' demo
在包含以下内容的演示文件中
watermelon banana
apple pear pineapple orange mango
strawberry cherry
kiwi pineapple lemon cranberry watermelon
orange plum cherry
kiwi banana plum
mango cranberry apple
lemon
输出结果为:
watermelon banana
apple pear pineapple orange mango
strawberry cherry
kiwi pineapple lemon cranberry watermelon
orange plum cherry
kiwi banana plum
mango cranberry apple
UNIQUE:lemon
不幸的是,如果提前使用,似乎无法处理 \ 3 反向引用。
是否有另一种方法可以通过另一个正则表达式或 Linux 框中提供的其他常用命令来实现此目的? (grep,sed,awk,...)
非常感谢
修改 不幸的是,许多解决方案仅适用于所提供的案例而且不完整,我为此道歉,它也应该适用于以下文本:
{watermelon || banana}
apple = ( pear pineapple orange mango )
strawberry cherry
kiwi = pineapple = lemon = cranberry = watermelon
orange - plum = cherry
kiwi = banana + plum
mango = cranberry && apple
lemon
如果它简化了问题,单词可能会以$或@为前缀。
答案 0 :(得分:13)
我看到你已经在使用Perl了。当你想用哈希计算某些东西总是一个很好的方法......
#!/usr/bin/perl -w
use strict;
my %hash = ();
my $str;
while(<>) {
$str .= $_;
$_ =~ s/\W+/ /g;
map {$hash{$_}++} split ' ', $_;
}
for (keys %hash){
my $word = $_;
if($hash{$word}==1) {
$str =~ s/\($word)/UNIQUE:$word/g;
}
};
print "$str\n";
将输出:
{watermelon || banana} apple = ( UNIQUE:pear pineapple orange mango ) UNIQUE:strawberry cherry kiwi = pineapple = lemon = cranberry = watermelon orange - plum = cherry kiwi = banana + plum mango = cranberry && apple lemon
使用正则表达式可能会很难。您需要两次运行整个文件。一次通过计算所有出现的单词和一次通过来标记唯一单词。
上面的代码片段读取输入一次,但是将整个原始文本保存在$ str中 - 如果输入很大,这显然是一个坏主意。
答案 1 :(得分:5)
单次执行regexp是不可能的。这样做的原因是因为在第一次替换完成后,内部游标在该匹配结束时移动,并且下次开始匹配时会忘记它背后的内容。事实上,不支持动态后视,因此您无法检查“此单词是否已在此匹配位置之前出现”。但是,你可以做的是每次执行正则表达式替换一个单词(因为这样你总是可以在字符串的开头锚定)。所以你要做的就是运行以下正则表达式,只要它取代了什么。
s/^.*?\K(?!UNIQUE:)\b(\w+)\b(?=(?:(?!\b\1\b).)*$)/UNIQUE:\1/s
答案 2 :(得分:2)
请注意,您需要更换操作的边界;否则,唯一的apple
可能会与非唯一cranapple
发生冲突,例如。
use strict;
use warnings;
use File::Slurp qw(read_file);
my %words;
my $content = read_file(shift @ARGV);
$words{$_} ++ for split /[\s\W]+/, $content;
my @uniq = grep { $words{$_} == 1 and length } keys %words;
$content =~ s/\b$_\b/UNIQUE:$_/g for @uniq;
print $content;
答案 3 :(得分:1)
我不知道为什么“柠檬”是独一无二的,但是我只想假设它只是一个单词出现,那么这里是一个awk脚本
awk '{
for(i=1;i<=NF;i++){
words[$i]++
if( words[$i] > 1){ delete words[$i] }
}
a[++d]=$0
}END{
for(i=1;i<=d;i++){
m=split(a[i],t," ")
for(k=1;k<=m;k++){
if ( t[k] in words ) {
t[k]="UNIQUE:"t[k]
}
}
for(w=1;w<=d;w++){
printf "%s ",t[w]
}
print ""
}
}' file
输出
$ more file
watermelon banana
apple pear pineapple orange mango
strawberry cherry
kiwi pineapple lemon cranberry watermelon
orange plum cherry
kiwi banana plum
mango cranberry apple
lemon
$ ./shell.sh
watermelon banana
apple UNIQUE:pear pineapple orange mango
UNIQUE:strawberry cherry
kiwi pineapple lemon cranberry watermelon
orange plum cherry
kiwi banana plum
mango cranberry apple
lemon
答案 4 :(得分:0)
你能把每个字放在一行吗?如果可以,您可以使用命令 uniq :
uniq -c yourfile
这样每个唯一单词的计数为1。