提取文件名的一部分

提取文件名的一部分

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"

相关内容