【问题标题】:Shell script, replace underscore + whitespace + possible numberShell脚本,替换下划线+空格+可能的数字
【发布时间】:2018-09-01 12:46:50
【问题描述】:

我正在尝试将文本中的任何地方的_ _1 或可能的_3_1 替换为★。所以它可以是空格或下划线之间的数字,最后它总是一个数字。

到目前为止,我只能替换一个数字,并且每次尝试添加更多数字时它都会停止工作。

这是行不通的行:

sed -e 's/ [0-9] /★/g' |

更新的整个代码:

echo
echo `cal` | 

sed "s/$(date +%e) / $(date +%e | sed 's/.*/★/g') /" | 

sed s'/Su Mo Tu We Th Fr Sa//g' | 

sed s'/  */  \|  /g' | 

sed 's/_[ 0-9]_[0-9]/★/g'|


sed s'/^  \|//' | sed s'/  \|//' | sed s'/\|/:  /' | 

sed s'/\|//g' | sed s"/$/      /"

这是原始输出:

这是我的代码之后的输出,下划线仍然存在:

原始字符串来自'cal', 出于某种原因,在当天放了一个 _ 。如果是 2.september 则表示 _ _2,如果是 30 日则表示 _3_0:

"September 2018 Su Mo Tu We Th Fr Sa _ _1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30"

我想要的输出 替换当前日期的星号。

"September 2018: ★ 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30"

【问题讨论】:

  • 请在您的问题中添加示例输入和该示例输入所需的输出。
  • @Cyrus 我现在更新了帖子,希望它更具描述性!
  • 至少在 OS X 上,echo $(cal) | od -a 表明今天的日期在左侧有一个退格键:_\b_\b1

标签: regex linux shell sed


【解决方案1】:

如果您使用od 检查cal 的输出,您会看到应该使用今天日期前面的_ 删除退格:

$ echo $(cal) | od -a
0000000    S   e   p   t   e   m   b   e   r  sp   2   0   1   8  sp   S
0000020    u  sp   M   o  sp   T   u  sp   W   e  sp   T   h  sp   F   r
0000040   sp   S   a  sp   _  bs  sp   _  bs   1  sp   2  sp   3  sp   4
0000060   sp   5  sp   6  sp   7  sp   8  sp   9  sp   1   0  sp   1   1
0000100   sp   1   2  sp   1   3  sp   1   4  sp   1   5  sp   1   6  sp
0000120    1   7  sp   1   8  sp   1   9  sp   2   0  sp   2   1  sp   2
0000140    2  sp   2   3  sp   2   4  sp   2   5  sp   2   6  sp   2   7
0000160   sp   2   8  sp   2   9  sp   3   0  nl  

今天是1,您可以在上面的输出中看到序列_ bs sp _ bs 1

要用 替换今天的日期,很容易用awk 替换这5 个字符和日期编号:

$ echo $(cal) | awk -v t=$(echo $(date +%e)) 'sub("_[\b] _[\b]"t,"★")' 
September 2018 Su Mo Tu We Th Fr Sa ★ 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

更简单,您可以使用 cal -h 关闭今天日期的突出显示,然后执行以下操作:

$ echo $(cal -h) | awk -v t=$(echo $(date +%e)) 'sub(" " t " "," ★ ")'
September 2018 Su Mo Tu We Th Fr Sa ★ 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

在这种情况下也可以使用sed

$ echo $(cal -h) | sed -E "s/ $(echo $(date +%e)) / ★  /" 
September 2018 Su Mo Tu We Th Fr Sa ★  2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

sed 在第一种情况下不像awk 那样容易使用,因为它缺乏对转义字符的一致支持,例如\b(GNU sed 除外)。

【讨论】:

    【解决方案2】:

    你可以使用:

    _[ 0-9]_[0-9]
    

    正则表达式演示here.

    $ echo "_ _1 _3_1" | sed 's/_[ 0-9]_[0-9]/★/g'
    ★ ★
    

    根据更新:

    $ echo "September 2018 Su Mo Tu We Th Fr Sa _ _1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30" | sed -r 's/ ([A-Za-z]{2} ){7}(_[ 0-9]_[0-9])/: ★/g'
    September 2018: ★ 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
    

    正则表达式演示here.

    【讨论】:

    • 谢谢!但这似乎在我的代码中不起作用,也许我误解了空格。您现在可以通过屏幕截图查看我更新的代码!
    • 您又添加了几行代码。如果您提供原始字符串和所需的输出,这将很有帮助。此外,使用文本比使用图像更容易。
    猜你喜欢
    • 2011-07-12
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多