TRNPRD.STD.BSRE.BREX.J.20190520.V02.PRET
我在 Linux 机器上有文件名,我只需要从中提取TRNPRD.STD.BSRE
.
我尝试了以下命令:
echo TRNPRD.STD.BSRE.BREX.J.20190520.V02.PRET | awk -F'.' '{for(i=0;++i<=NF-5;) printf $i".";}'
但它返回了所需的结果,并在末尾有一个我不需要的额外点:
TRNPRD.STD.BSRE.
谁能告诉我我在这里缺少什么?
答案1
我建议cut
在这里使用,因为awk
对于这项任务来说有点矫枉过正。
$ echo TRNPRD.STD.BSRE.BREX.J.20190520.V02.PRET | cut -d . -f -3
TRNPRD.STD.BSRE
答案2
您的awk
命令添加了 ,.
因为您告诉它打印$i
,然后添加.
。所以它以额外的.
.你可以这样做:
$ echo TRNPRD.STD.BSRE.BREX.J.20190520.V02.PRET |
awk -F'.' '{for(i=0;++i<=NF-6;) printf $i"."; print $(NF-5)}'
TRNPRD.STD.BSRE
或者,直接打印前 3 个:
$ echo TRNPRD.STD.BSRE.BREX.J.20190520.V02.PRET |
grep -oP '^([^.]+\.){2}[^.]+'
TRNPRD.STD.BSRE
当然,你也可以使用原来的方法,只删除多余的.
:
$ echo TRNPRD.STD.BSRE.BREX.J.20190520.V02.PRET |
awk -F'.' '{for(i=0;++i<=NF- 5;) printf $i".";}' | sed 's/\.$//'
TRNPRD.STD.BSRE$
然而,最好和最简单的解决方案是cut
正如@Panki建议的。
答案3
如果要从字符串中删除最后五个点分隔的子字符串:
$ name=TRNPRD.STD.BSRE.BREX.J.20190520.V02.PRET
$ echo "${name%.*.*.*.*.*}"
TRNPRD.STD.BSRE
这适用标准参数扩展从 值的末尾删除与给定模式匹配的子字符串$name
。
如果你想保持字符串中前三个点分隔的子字符串:
$ name=TRNPRD.STD.BSRE.BREX.J.20190520.V02.PRET
$ echo "${name%.${name#*.*.*.}}"
TRNPRD.STD.BSRE
$name
首先从using中删除前三位${name#*.*.*.}
(#
从左侧/开始删除,%
从右侧/末尾删除),然后使用该结果删除字符串的尾部,留下前三个点分隔位。
只要 in 中的值$name
不包含换行符(这是使用标准文本处理工具的任何解决方案的问题),以下建议就有效。
您的awk
代码始终在每个字段的末尾打印一个点。为了让它稍微更健壮,你可以使用类似的东西
awk -v OFS="." '{ n=split($0,a,"\."); $0=""; for (i=1; i<=3 && i<=n; ++i) $i=a[i]; print }' <<<"$name"
这会将值按点分割,然后创建该值前三个部分的输出记录并打印它(输出字段分隔符 ,OFS
设置为点)。
要使其丢弃最后五位而不是保留前三位:
awk -v OFS="." '{ n=split($0,a,"\."); $0=""; for (i=1; i<=n-5; ++i) $i=a[i]; print }' <<<"$name"