【问题标题】:Remove all text from last dot in bash从bash中的最后一个点删除所有文本
【发布时间】:2014-10-29 14:56:38
【问题描述】:

我有一个名为 test.txt 的文件,其中有:

abc.cde.ccd.eed.12345.5678.txt
abcd.cdde.ccdd.eaed.12346.5688.txt
aabc.cade.cacd.eaed.13345.5078.txt
abzc.cdae.ccda.eaed.29345.1678.txt
abac.cdae.cacd.eead.18145.2678.txt
aabc.cdve.cncd.ened.19945.2345.txt

如果我想删除第一个 . 之外的所有内容,例如:

cde.ccd.eed.12345.5678.txt
cdde.ccdd.eaed.12346.5688.txt
cade.cacd.eaed.13345.5078.txt
cdae.ccda.eaed.29345.1678.txt
cdae.cacd.eead.18145.2678.txt
cdve.cncd.ened.19945.2345.txt

那我就去做

for i in `cat test.txt`; do echo ${i#*.}; done

但如果我想删除最后一个 . 之后的所有内容,例如:

abc.cde.ccd.eed.12345.5678
abcd.cdde.ccdd.eaed.12346.5688
aabc.cade.cacd.eaed.13345.5078
abzc.cdae.ccda.eaed.29345.1678
abac.cdae.cacd.eead.18145.2678
aabc.cdve.cncd.ened.19945.2345

我该怎么办?

【问题讨论】:

  • 查看BASH FAQ #1 了解逐行读取文件的正确方法。不要使用for 循环。

标签: linux bash awk grep


【解决方案1】:

使用 awk:

awk 'BEGIN{FS=OFS="."} NF--' file

如果没有空行,这有效。它将输入和输出字段分隔符设置为点.。然后,减少一个字段的数量,以便将最后一个字段排除在外。然后它执行默认的awk动作:{print $0},即打印该行。

与sed:

sed 's/\.[^.]*$//' file

这会捕获. + text + end of line 的最后一个块,并将其替换为空。也就是说,它会删除它。

使用rev 和cut:

rev file | cut -d'.' -f2- | rev

rev 反转行,以便cut 可以从第二个单词打印到末尾。然后,rev 回来得到正确的输出。

与bash:

while ISF= read -r line
do
  echo "${line%.*}"
done < file

这将执行字符串操作,包括从变量 $line 内容的末尾替换 .* 的最短匹配项。

grep:

grep -Po '.*(?=\.)' file

前瞻打印最后一个点之前的内容。

全部返回:

abc.cde.ccd.eed.12345.5678
abcd.cdde.ccdd.eaed.12346.5688
aabc.cade.cacd.eaed.13345.5078
abzc.cdae.ccda.eaed.29345.1678
abac.cdae.cacd.eead.18145.2678
aabc.cdve.cncd.ened.19945.2345

【讨论】:

  • @Kent 很高兴 :)
  • 谢谢! grep、sed、awk、cut 和 bash 总是有很好的聚会:) 另外,添加了一些解释。
  • 你可以把{NF--}1改成NF--
猜你喜欢
  • 2011-05-09
  • 2011-06-20
  • 1970-01-01
  • 1970-01-01
  • 2011-03-06
  • 2015-01-02
  • 2011-03-06
  • 1970-01-01
相关资源
最近更新 更多