sed - 删除零 - /08/ 到 /8/

sed - 删除零 - /08/ 到 /8/

我需要使用什么 sed 命令将 /08/ 转换为 /8/?

我希望去掉命令输出中所有多余的 0。

我已经把它减少到一个讨厌的额外 0。

sed -ie 's/\/0[1-9]\//\/[1-9]\//g' ~/tmp

输出:at 12:27 AM on 5/[1-9]

sed -ie 's/\/0?\//\/?\//g' ~/tmp

输出:at 12:27 AM on 5/08

完整脚本:

#!/bin/bash

echo $@ > ~/tmp
sed -ie 's/\/0[1-9]\//\/[1-9]\//g' ~/tmp
AA=`awk '{print $2}' ~/tmp | awk -F : '{print $1":"$2}' | sed 's/^0*//'`
BB=`awk '{print $3}' ~/tmp`
CC=`awk '{print $1}' ~/tmp | awk -F / '{print $1"/"$2}' | sed 's/^0*//'`
DD=`awk '{print $5}' ~/tmp | awk -F : '{print $1":"$2}' | sed 's/^0*//'`
EE=`awk '{print $6}' ~/tmp`
FF=`awk '{print $4}' ~/tmp | awk -F / '{print $1"/"$2}' | sed 's/^0*//'`

if [ $# = 3 ]; then
    echo "at $AA $BB on $CC"

elif [ $# = 6 ] && [ $CC = $FF ]; then
    echo "from $AA $BB to $DD $EE on $FF"

elif [ $# = 6 ]; then
    echo "from $AA $BB on $CC to $DD $EE on $FF"
fi
rm ~/tmp

输入输出示例(别名=dt):

使用当前的 sed 命令

dt 05/08/2017 02:27:25 AM

5/[1-9] 凌晨 2:27


没有第一个 sed 命令

dt 05/08/2017 02:27:25 AM

5 月 8 日凌晨 2:27


已解决--第三行替换为sed -rie 's/\/0(.?)/\/\1/g' ~/tmp

dt 05/08/2017 01:03:56 AM

输出:5 月 8 日凌晨 1:03

答案1

笔记:这是经过编辑的答案,以使解决方案尽可能通用。查看编辑历史记录以查看最初所做的操作,并查看对先前答案的问题的评论。

这里的关键是通过()-r对扩展正则表达式进行分组。对模式进行分组()将允许您根据它们在通过\NUMBER符号中的位置来引用它们。特别是,这是我想到的:

sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g' 

内容如下:

  • 匹配零个或多个为零的字符
  • 将后面的一个或多个非零字符组合在一起
  • 然后查找斜杠后跟零个或多个零字符
  • 并将后面的一个或多个非零字符组合在一起

实际上,对于可变数量的零,这也是如此:

$ echo "at 12:27 AM on 11/08/2017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g'                                                                         
at 12:27 AM on 11/8/2017
$ echo "at 12:27 AM on 00000011/000008/00002017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g'                                                           
at 12:27 AM on 11/8/00002017
$ echo "at 12:27 AM on 011/08/00002017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g'                                                                    
at 12:27 AM on 11/8/00002017
$ echo "at 12:27 AM on 000000011/0000008/00002017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g'                                                         
at 12:27 AM on 11/8/00002017

请注意,如果需要的话,这足以保留年份部分中的任何内容。如果我们也想摆脱它 - 我们还可以添加第三组。

$ echo "at 12:27 AM on 005/0025/0002017" | sed -r 's/0*([^0]+)\/0*([^0]+)\/0*([^0]+)/\1\/\2\/\3/g'                                                    
at 12:27 AM on 5/25/2017

这也适用于其他字符(这不是必需的,但很高兴拥有):

$ echo "at 12:27 AM on 0November/00Fifth/2017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g'                                                             
at 12:27 AM on November/Fifth/2017

答案2

sed -e 's/\<00*\([1-9]\)/\1/g' input_data

工作:此正则表达式查找一个整数 [0-9],其左侧是一串 0,并且这些零由分词符界定\<

答案3

sed -ie 's/\/0?\//\/?\//g' ~/tmp

首先,您可以使用斜杠以外的其他字符作为 的分隔符s///,这样您就可以使用斜杠而无需转义。其次,如 @斯特凡注意,将被视为备份文件的扩展-iee,因此您将获得一个名为tmpe.我会更改扩展名(或删除它),并重写如下:

sed -i.bak -e 's,/0?/,/?/,g' ~/tmp

现在,可以更容易地看到它匹配的实际模式:字符串///0/文字字符串/0?/,它被替换为/?/。 (在 ERE 中,?会匹配前一组的零个或一个副本,因此零个或一个0)。

问号在替换中并不特殊,所以它会按字面意思出现。正如其他答案中所述,您需要使用分组((...)使用 ERE 或\(...\)BRE)来捕获模式的一部分,然后\1在替换中将它们放回去。

所以像这样:

sed -i.bak -Ee 's,/0*([1-9]),/\1,g' ~/tmp

但请注意,它仍然需要前面的斜杠,因此第一个零05/08/2017不会被替换。

拉克什的使用\<如果您想从所有单词中删除前导零,这可能是明智之举。话又说回来,更改12:03:0412:3:4可能不是您想要的。


最后一个示例可以使用一个命令来完成更改05/08/2017 01:03:56 AM为:at 1:03 AM on 5/8sed

$ echo '05/08/2017 01:03:56 AM' | 
  sed -Ee 's,0*([0-9]+)/0*([0-9]+)/[0-9]+ 0*([0-9]+):([0-9]+):[0-9]+ ([AP]M),at \3:\4 \5 on \1/\2,'
at 1:03 AM on 5/8

我没有看你想接受什么其他输入格式。

答案4

您不能在替换文本中使用正则表达式。你的意思是

sed 's/0\([0-9]\)/\1/'

相关内容