我有一个包含数据的文件,如下所示:
"google1|yoo|dummy|yes|wow|/" + VARIABLE + "/"
"google2|hub|lab|dummy|yes|/" + VARIABLE + "/"
"google3|short|lab|yoo|/" + VARIABLE + "/"
"google4|hello|good-guy|bad-girl|lol|dummy|/" + VARIABLE + "/"
"google5|good-guy|a4-123|yoo|/" + VARIABLE + "/"
"google6|bad-girl|b4-124|hub|/" + VARIABLE + "/"
现在,我想获取分隔符“|”之间的字符串列表(管道)。
输出应该是
yoo
dummy
yes
wow
hub
hello
good-guy
bad-girl
a4-123
b4-124
dummy
lol
short
lab
基本上,我想在分隔符过滤器之后从字符串列表中获得唯一值。我尝试使用 awk 作为
awk -F"|" '{gsub(/\).*/,"",$2);print $2}' file
但是,我得到了错误的数据。
答案1
如果你有grep
选项pcre
:
$ grep -oP '\|\K[^|]+(?=\|)' ip.txt | sort -u
a4-123
b4-124
bad-girl
dummy
good-guy
hello
hub
lab
lol
short
wow
yes
yoo
-o
只打印匹配的模式-P
使用 PCRE 正则表达式\|\K
正向后查找,看看|
在我们要提取的字符串之前是否存在- 类似地,
(?=\|)
正向前视查看要|
提取的字符串后面是否有
- 类似地,
[^|]+
要提取的字符串 - 只需求反|
并获取一个或多个此类字符sort -u
获得独特的价值
如果您想保留这些字符串的查找顺序:
$ grep -oP '\|\K[^|]+(?=\|)' ip.txt | awk '!seen[$0]++'
yoo
dummy
yes
wow
hub
lab
short
hello
good-guy
bad-girl
lol
a4-123
b4-124
答案2
如果你不关心顺序,你可以使用 perl hash 来确保唯一性,例如
$ perl -lne '$h{$_}++ for /(?<=\|).*?(?=\|)/g; END{print for keys %h}' file
short
b4-124
lol
yes
bad-girl
lab
yoo
good-guy
hub
dummy
hello
a4-123
wow
答案3
那么以下呢?
cut file -d'|' -f2,3,4 | tr '|' '\n'
上述命令将打印固定数量的列 (3)。如果您想打印可变数量的列,直到第一次出现/
,您可以使用类似以下内容的内容:
cut -d'/' -f1 file | cut -d'|' -f2- | tr '|' '\n'
答案4
您的输出有“虚拟”重复。这就是我通过下面的脚本得到的结果——
awk -f f1.awk /tmp/f1
short
hub
wow
hello
a4-123
b4-124
yes
yoo
lol
bad-girl
good-guy
lab
dummy
cat f1.awk
{
n=split($1,a,"|")
for(i=2; i<n; i++) {
arr[a[i]] = a[i]
}
}
END{
for (var in arr)
print(var)
}