shell 这里正则表达式的使用是否符合POSIX,所使用的代码是否适合所描述的问题?

qvtsj1bj  于 2023-10-23  发布在  Shell
关注(0)|答案(2)|浏览(126)

根据我之前的问题here,请参阅下面我的问题的完整形式。

代码用例

当前的代码是一个module,用于polybar,一个可定制的状态栏。根据第一个链接,polybar是使用配置文件绘制的,每个被调用的bar(例如,通过运行polybar mybar)读取任何给定模块的配置文件。一个完整的例子可以在这里看到。自定义或用户定义的模块通过调用相关的脚本文件来加载。例如:

[module/test]
type = custom/script
exec = some/script/file
tail = true

Polybar至少接受shell脚本和python脚本(也许还有其他脚本,尽管我没有测试过)。对于这个问题,我关心的是我的shell脚本的适当性,而不是它与polybar的接口(目前它可以按预期工作;尽管正如@EdMorton解释的那样,这可能不是预期的功能,因此这个问题)。

当前代码

下面是我的代码的一个最小的工作示例。

#!/bin/bash

smile=#d1dadf;
sad=#ff5833;
angry=#1a88a4;
laugh=#daf7a6;

while true; do

    # get hour
    time=$(date +%_H -u);

    # set empty hour
    timeShow=TEST;

    # set empty emoji
    emoji=;

    if [ $time -ge 0 ] && [ $time -lt 6 ];
    then
            emoji=%{F$smile}😀%{F-}
    elif [ $time -ge 6 ] && [ $time -lt 12 ];
    then
            emoji=%{F$sad}😢%{F-}
    elif [ $time -ge 12 ] && [ $time -lt 18 ];
    then
            emoji=%{F$angry}😡%{F-}
    elif [ $time -ge 18 ] && [ $time -ne 0 ];
    then
            emoji=%{F$laugh}😆%{F-}
    fi

    if [[ "$emoji" =~ [😢] ]];
    then
        ((timeShow = time - 1))
    elif [[ "$emoji" =~ [😡] ]];
    then
        ((timeShow = time - 2))
    elif [[ "$emoji" =~ [😆] ]];
    then
        ((timeShow = time - 3))
    fi

    echo "$timeShow:$(date '+%M' -u) $emoji"
    
    sleep 1
done

输入(和输出)说明

按原样运行脚本不需要输入(输出是从脚本本身计算的)。因此,运行脚本只需通过以下方式完成:

./script.sh

输出应该(并且确实)返回格式化的时间,沿着 Package 在颜色格式标签中的表情符号,如上所述。
目前的程序从date获取当前UTC小时。然后修改该值(存储在变量time中)并将其存储在timeShow中。假设有一个特定的小时数范围(因此也是emoji),然后脚本通过减去1、2或3来修改timeShow。emoji在字符串emoji中找到,通过执行regex操作来定位字符,该字符由颜色格式 Package 。

给定硬编码输入的预期输出

更改以下内容:

while true; do... done

对此:

for time in 8 12 22 0; do... done

此外,应更改以下行以匹配以下内容:

# get hour
#time=$(date +%_H -u);

# set default hour
timeShow=0

假设脚本在整点运行,应给予以下预期输出。
环路1(上午8点)(偏移-1):

7:00 %{F#ff5833}😢%{F-}

环路2(下午12时)(偏移-2):

10:00 %{F#1a88a4}😡%{F-}

环路3(在10 pm)(偏移-3):

19:00 %{F#daf7a6}😆%{F-}

循环4(上午12点)(偏移0):

0:00 %{F#d1dadf}😀%{F-}

期望输出

脚本按预期工作。然而,如上所述,这可能不是偶然的。这个问题的目的是了解所使用的方法是否产生了正确的输出,或者只是碰巧产生了正确的输出。目前正则表达式通过使用[😀]隔离字符。对于任何可能包含2个或更多字符的表情符号,例如M-bM-^XM-^A$,因此隔离表情符号,[😀]可能不准确,因为它将匹配第一个对应字符,导致不期望或意外的行为。这里提供了对该问题的进一步解释。

vsmadaxz

vsmadaxz1#

与其将$emoji与regexp匹配,不如在设置emoji时设置另一个变量,并在设置timeShow时使用该变量。

#!/bin/bash

smile=#d1dadf;
sad=#ff5833;
angry=#1a88a4;
laugh=#daf7a6;

while true; do

    # get hour
    time=$(date +%_H -u);

    # set empty hour
    timeShow=TEST;
    timeOffset=0

    # set empty emoji
    emoji=;

    if [ $time -ge 0 ] && [ $time -lt 6 ];
    then
            emoji=%{F$smile}😀%{F-}
            timeOffset=3
    elif [ $time -ge 6 ] && [ $time -lt 12 ];
    then
            emoji=%{F$sad}😢%{F-}
            timeOffset=1
    elif [ $time -ge 12 ] && [ $time -lt 18 ];
    then
            emoji=%{F$angry}😡%{F-}
            timeOffset=2
    elif [ $time -ge 18 ] && [ $time -ne 0 ];
    then
            emoji=%{F$laugh}😆%{F-}
            timeOffset=3
    fi

    timeshow=$((time - timeOffset)

    echo "$timeShow:$(date '+%M' -u) $emoji"
    
    sleep 1 &
    wait
done
ktecyv1j

ktecyv1j2#

这可能是你想做的事情:

#!/usr/bin/env bash

emojis[3]=%{F#d1dadf}😀%{F-}
emojis[1]=%{F#ff5833}😢%{F-}
emojis[2]=%{F#1a88a4}😡%{F-}
emojis[0]=%{F#daf7a6}😆%{F-}

while true; do

    # get hour
    TZ=UTC printf -v hour '%(%k)T' -1

    if   (( hour == 0 )); then delta=0
    elif (( hour <  6 )); then delta=3
    elif (( hour < 12 )); then delta=1
    elif (( hour < 18 )); then delta=2
    else                       delta=0
    fi

    emoji="${emojis[$delta]}"
    hourShow=$(( hour - delta ))
    TZ=UTC printf -v min '%(%M)T' -1

    printf '%d:%02d %s\n' "$hourShow" "$min" "$emoji"

    sleep 1
done

因为你在赋值上下文中使用了bash和算术运算,所以没有理由不在比较中也使用它们,没有必要总是在if-else中测试前一个范围的结束,我也没有理由想到使用sleep 1 &; wait而不仅仅是sleep 1
在这里,它被调整为使用OP提供的特定小时值进行测试,在UTC下午2:58完成:

$ cat tst.sh
#!/usr/bin/env bash

emojis[3]=%{F#d1dadf}😀%{F-}
emojis[1]=%{F#ff5833}😢%{F-}
emojis[2]=%{F#1a88a4}😡%{F-}
emojis[0]=%{F#daf7a6}😆%{F-}

#while true; do
for hour in 8 8 12 22 0; do

    # get hour
    #TZ=UTC printf -v hour '%(%k)T' -1

    if   (( hour == 0 )); then delta=0
    elif (( hour <  6 )); then delta=3
    elif (( hour < 12 )); then delta=1
    elif (( hour < 18 )); then delta=2
    else                       delta=0
    fi

    emoji="${emojis[$delta]}"
    hourShow=$(( hour - delta ))
    TZ=UTC printf -v min '%(%M)T' -1

    printf '%d:%02d %s\n' "$hourShow" "$min" "$emoji"

    sleep 1
done
$ ./tst.sh
7:58 %{F#ff5833}😢%{F-}
7:58 %{F#ff5833}😢%{F-}
10:58 %{F#1a88a4}😡%{F-}
22:58 %{F#daf7a6}😆%{F-}
0:58 %{F#daf7a6}😆%{F-}

您可能希望在printfs中将每个%d更改为%02d,以便获得2位数的小时值,例如。07:58而不是7:58

相关问题