替换从后面计数的特定索引处的字符

替换从后面计数的特定索引处的字符

我想更改我创建的字符串中的一些字符。我制作了一个文件列表,并且需要从每个文件中附加“统计”信息。例如,文件名 "K181_111126.CATProduct"结果为"K181_111126.CATProduct.2011-11-28 13:33:33.722342000 +0100".最后 16 个字符我不需要,我用以下方法解决了它:

find . -type f -exec stat -c%n.%y {} \; | sed 's/.\{16\}$//'

结果:"K181_111126.CATProduct.2011-11-28 13:33:33" 我的问题是,我需要用“-”更改日期和时间之间的空格(后面的第9个字符),并用点“”更改时间(13:33:33)中的所有“:”。
这些绳子的长度都不一样,所以我只能从后面数。

答案1

使用稍长的正则表达式同时替换空格和冒号。

find . -type f -exec stat -c%n.%y {} \; |
sed 's/ \(..\):\(..\):\(..\).\{16\}$/-\1.\2.\3/'

匹配倒数第24个字符之前的空格,然后我们匹配并捕获接下来的2个字符,一个逗号,接下来的2个,一个comra,还有另外2个;然后,最后 16 个被匹配并替换为任何内容。可以使用反向引用调用第一个捕获的表达式\1(第二个使用\2等)。换句话说,空格后面的两位数字被自身“替换”,即有效保留,后面跟着一个点,接下来的两个数字等。

答案2

我想这就是您正在寻找的:

$ s='K181_111126.CATProduct.2011-11-28 13:33:33.722342000 +0100'
$ echo "$s" | rev | sed -E 's/.{16}//; s/:/./; s/:/./; s/ /-/' | rev
K181_111126.CATProduct.2011-11-28-13.33.33

这用于rev按字符方式反转输入行,以便更容易处理,最后rev再次

  • s/.{16}//删除前 16 个字符
  • s/:/./; s/:/./将前两个更改:.
  • s/ /-/将第一个空格更改为-

答案3

find ... |
sed -Ee '
  s/.{16}$//
  :a;s/:([^:[:blank:]]*)$/.\1/;ta
  s/[[:blank:]]([^[:blank:]]+)$/-\1/
'

在像您一样删除尾随 16 个字符之后,我们设置一个循环来逐步转换 - :> .,完成后,将最后一个最空白的字符更改为破折号。这是必要的,因为文件名也可能包含空白字符,我们需要忽略它们。

相关内容