我要解析数据googleapis.txt
bucket,abc-def-ghi-45gjd4-wwxis
bucket,dde-wwq-ooi-66ciow-po22q
instance,jkl-mno-1-zzz-68dkakw-oo9w8
disk,pqr-stu-10-kuy-l2oxapw-rp4lt
我期望像下面这样的结果
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy
我想我必须更改-
为空格,然后运行此命令
cat googleapis.txt | awk '{$NF="";sub(/[ \t]+$/,"")}1' | awk '{$NF="";sub(/[ \t]+$/,"")}1'
我从这个得到了https://stackoverflow.com/a/27794421/8162936
解析后,我将把空格改为连字符
-
。
有谁知道解析它的最佳实践或单行 shell 命令吗?谢谢大家
答案1
与sed
你一起可以做:
sed -E 's/(-[^-]*){2}$//' infile
从每行末尾匹配-anything
两次类似的模式并将其删除。(...){2}
$
答案2
$ sed 's/-[[:alnum:]]*-[[:alnum:]]*$//' file
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy
这用于sed
匹配每行上最后两个破折号分隔的子字符串并将其删除。 [[:alnum:]]
将匹配任何字母数字字符。
您可以将其缩短为
sed 's/\(-[[:alnum:]]*\)\{2\}$//' file
-[[:alnum:]]*
即,匹配并删除每行末尾的两组ath。
使用GNU awk
,你也可以这样做
$ awk -F '-' 'BEGIN { OFS=FS } { NF -= 2; print }' file
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy
但NF
这样的改变是不可移植的,应该避免(不能保证它会改变当前记录)。awk
例如,它不适用于 BSD 。
使用 standard awk
,而不诉诸 using sub()
(这只是模仿sed
),您将必须从您想要使用的字段重新创建当前记录(在我们的例子中,除了最后两个破折号分隔的字段之外的所有字段):
$ awk -F '-' 'BEGIN { OFS=FS } { nf = split($0,a) - 2; $0=""; for (i=1; i<=nf; ++i) $i = a[i]; print }' file
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy
答案3
与rev
和cut
:
rev file | cut -d'-' -f3- | rev
将行、cut
字段 3 反转到行尾,然后再次反转文本。
使用grep
(和 PCRE):
grep -Po '.*(?=(-[^-]*){2}$)' file
-P
使用与 perl 兼容的正则表达式,其中(?...)
包含两个匹配项,-
后跟任何非-
字符-o
只打印匹配的部分
答案4
您可以通过多种方式完成此操作,如下所示:
$ perl -F- -pale '$"="-";$#F-=2;$_="@F"' file
在破折号上分割线,将数组元素连接器设置为破折号,剪辑最后两个元素,并将当前行设置为用破折号连接的数组。
$ awk -F- '{
t = $1
for ( i=2; i<NF-1; i++ ) t = t FS $i
$0 = t
}1' file
这是普通字符串处理:
$ perl -lne 'print substr($_, 0, rindex($_,"-",-1+rindex($_,"-")))' file
。
$ sed -ne '
y/-/\n/
:a;h;s/\n/-/;/\n.*\n/ba
g;P
' file
结果:
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy