删除行尾的一个或多个字段,以“-”分隔

Nic*_*uff 8 awk text-processing

我要解析数据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
Run Code Online (Sandbox Code Playgroud)

我期待下面的结果

bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy
Run Code Online (Sandbox Code Playgroud)

我想我必须更改-为空格然后运行此命令

cat googleapis.txt | awk '{$NF="";sub(/[ \t]+$/,"")}1' | awk '{$NF="";sub(/[ \t]+$/,"")}1'
Run Code Online (Sandbox Code Playgroud)

我从这个/sf/answers/1945609501/得到了 解析后,我将把空格-回连字符。

有谁知道解析它的最佳实践或单行 shell 命令?谢谢大家

αғs*_*нιη 10

sed你可以这样做:

sed -E 's/(-[^-]*){2}$//' infile
Run Code Online (Sandbox Code Playgroud)

从每行的末尾匹配-anything两次类似的模式并将其删除。(...){2}$


Kus*_*nda 7

$ sed 's/-[[:alnum:]]*-[[:alnum:]]*$//' file
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy
Run Code Online (Sandbox Code Playgroud)

这用于sed匹配每行上最后两个以破折号分隔的子字符串并删除它们。 [[:alnum:]]将匹配任何字母数字字符。

您可以将其缩短为

sed 's/\(-[[:alnum:]]*\)\{2\}$//' file
Run Code Online (Sandbox Code Playgroud)

即,匹配并删除-[[:alnum:]]*每行末尾的两组a 。

使用 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
Run Code Online (Sandbox Code Playgroud)

但是NF像这样更改是不可移植的,应该避免(不能保证它会更改当前记录)。awk例如,它不适用于 BSD 。

使用标准awk,不诉诸使用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
Run Code Online (Sandbox Code Playgroud)