V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
hujianxin
V2EX  ›  程序员

今天有个小需求,用 awk 和 sed 貌似不能很好的完成任务,打算转战 perl 了

  •  
  •   hujianxin · 2018-12-05 20:38:20 +08:00 · 6741 次点击
    这是一个创建于 2203 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有一个文件,a.txt ,文容如下:

    0689LM  name=S:321, password=154adfv839473, value=37461278216723
    1633LM  name=S:241, password=15sdf78839611, value=21
    1121LM  name=S:673, password=1543978839612, value=1230
    1212LM  name=S:854, password=fd43978df9621, value=383242544
    3323LM  name=S:456, password=sd9788396sdd3, value=11211
    3322LM  name=S:234, password=dsfas78839623, value=23121
    4238LM  name=S:254, password=1fdsafdsafdsa, value=324342
    51LM    name=S:903, password=fdsafsdafsdaf, value=43543
    2389LM  name=S:572, password=fdsfdsdfwefff, value=2343235
    91452LM name=S:842, password=sdfwef23dffds, value=3434324
    9553LM  name=S:fed, password=23fdssfdss32f, value=10501342176
    

    需求:输出第一列的反转,name=S:之后的数字,value 之后的数值,如下:

    ML9860 321 37461278216723
    ML3361 241 21
    ML1211 673 1230
    ML2121 854 383242544
    ML3233 456 11211
    ML2233 234 23121
    ML8324 254 324342
    ML15 903 43543
    ML9832 572 2343235
    ML25419 842 3434324
    ML3559 fed 10501342176
    

    awk,不好实现第一列的反转

    sed,不好显示抓取 name=S:之后的数字(需要非贪婪)

    当然,也可能是我才疏学浅,如果各位大佬有更好的解决方法,欢迎指教。

    perl -aE '/name=S:(.*?),.*?value=(.*)/; $a = reverse $F[0]; say "$a $1 $2"' a.txt

    第 1 条附言  ·  2018-12-06 16:08:19 +08:00
    题目中所提工具有:awk、sed、perl。

    如果有人觉着这些东西落伍了,不够好(比如你觉着写 excel 更好、python 更好),那么你把代码提出来,大家一起讨论一下。简单的来说,就是 show me your code。

    另外,题目中并没有提 shell 这门语言,如果你想喷想疯了的话,自己开一个帖子去喷 shell 如何?
    86 条回复    2018-12-07 14:44:43 +08:00
    liprais
        1
    liprais  
       2018-12-05 20:46:02 +08:00
    想用 perl 就用 perl 呗
    反正之后你会发现三十秒看不懂的东西都得重写
    hujianxin
        2
    hujianxin  
    OP
       2018-12-05 20:47:24 +08:00
    @liprais oneliner 从来都不是为了复用的啊
    zbinlin
        3
    zbinlin  
       2018-12-05 20:59:28 +08:00
    只用 sed 就可以呀:

    sed -r 's/^([[:digit:]]+)([A-Z]+)\s+name=S:([^,]+),.+value=(.+)$/\2\1 \3 \4/'
    zbinlin
        4
    zbinlin  
       2018-12-05 21:02:31 +08:00
    @zbinlin 呃,没看到第一列的数字反转了
    hujianxin
        5
    hujianxin  
    OP
       2018-12-05 21:13:14 +08:00
    @zbinlin 这个反转,估计用 sed 的保持空间协助一下也能搞定,但是太难了
    yiyiwa
        6
    yiyiwa  
       2018-12-05 21:14:05 +08:00
    这样有点慢啊

    awk -F '[: ,]' '{"rev<<<"$1|getline a;print a,$3,$NF}'
    yiyiwa
        7
    yiyiwa  
       2018-12-05 21:19:10 +08:00
    少个+,
    awk -F '[: ,]+' '{"rev<<<"$1|getline a;print a,$3,$NF}'
    hujianxin
        8
    hujianxin  
    OP
       2018-12-05 21:21:20 +08:00
    @yiyiwa 这条语句在我这里有语法错误呢

    sh: 1: Syntax error: redirection unexpected
    name=S value=37461278216723
    sh: 1: Syntax error: redirection unexpected
    name=S value=21
    sh: 1: Syntax error: redirection unexpected
    name=S value=1230
    sh: 1: Syntax error: redirection unexpected
    name=S value=383242544
    sh: 1: Syntax error: redirection unexpected
    name=S value=11211
    sh: 1: Syntax error: redirection unexpected
    name=S value=23121
    sh: 1: Syntax error: redirection unexpected
    name=S value=324342
    sh: 1: Syntax error: redirection unexpected
    value=43543
    sh: 1: Syntax error: redirection unexpected
    name=S value=2343235
    sh: 1: Syntax error: redirection unexpected
    842 value=3434324
    sh: 1: Syntax error: redirection unexpected
    hujianxin
        9
    hujianxin  
    OP
       2018-12-05 21:21:58 +08:00
    @yiyiwa 还是同样的错误
    yiyiwa
        10
    yiyiwa  
       2018-12-05 21:25:53 +08:00
    awk -F '[: ,=]+' '{s=length($1);for(i=0;i<s;i++)k=k""substr($1,s-i,1);print k,$4,$NF;k=j}'
    rrfeng
        11
    rrfeng  
       2018-12-05 21:27:50 +08:00
    翻转第一列:

    echo .... | while read a b; do echo $(rev <<< $a) $b;done

    如果只有一行的话不需要 while

    echo .... | { read a b; echo $(rev <<< $a) $b; }
    weyou
        12
    weyou  
       2018-12-05 21:29:06 +08:00 via Android
    首先 awk 是可以用循环来反转的,就是麻烦点。第二,rev 命令很多系统都是自带的吧,为什么不用
    rrfeng
        13
    rrfeng  
       2018-12-05 21:31:23 +08:00
    @yiyiwa
    需要关闭管道,在处理行尾加上 close "rev<<<" 试试
    ywgx
        14
    ywgx  
       2018-12-05 21:34:02 +08:00   ❤️ 1
    对 vimer 来说,也就是录制个宏,播放一下而已
    hcymk2
        15
    hcymk2  
       2018-12-05 21:38:08 +08:00
    awk 可以自定义函数。
    hujianxin
        16
    hujianxin  
    OP
       2018-12-05 22:08:41 +08:00
    @yiyiwa 这个我也想到啦,但是稍微有点复杂了,长了一些。
    @ywgx 感觉分工还不太一样

    @hcymk2 自定义函数就不是一行了。。
    codechaser
        17
    codechaser  
       2018-12-05 22:18:46 +08:00 via Android
    你们说的我根本看不懂……
    likuku
        18
    likuku  
       2018-12-05 22:26:58 +08:00
    额... 我是突然点进了今天的 黑魔法 9 级课程了么?

    别说 awk sed 了,shell 开始需要用到 判断 语句 我都果断直接用 py3 了。
    zbinlin
        19
    zbinlin  
       2018-12-05 22:35:34 +08:00   ❤️ 1
    @zbinlin

    paste -d' ' <(sed -rn 's/^([^ ]+*).+$/\1/p' <filename> | rev) <(sed -rn 's/^.+name=S:([^,]+),.+value=(.+)$/\1 \2/p' <filename>)
    ToT
        20
    ToT  
       2018-12-05 23:24:40 +08:00
    能用 pandas 么。。。。
    xpresslink
        21
    xpresslink  
       2018-12-05 23:37:00 +08:00
    随便用个编程语言打开文件逐行遍历一下就可以。
    DAPTX4869
        22
    DAPTX4869  
       2018-12-05 23:59:05 +08:00
    shell 这堆玩意....瞎了
    realpg
        23
    realpg  
       2018-12-06 00:33:23 +08:00
    python 不好么
    其实更好的解决方案是 EXCEL
    livepps
        24
    livepps  
       2018-12-06 00:47:41 +08:00 via Android
    python 分分钟的事情
    agagega
        25
    agagega  
       2018-12-06 01:03:06 +08:00
    我想了想用 Ruby,也可以一行搞定,结果可能可读性比你的 Perl 稍微高点点,也没差太多...
    yue9944882
        26
    yue9944882  
       2018-12-06 01:05:37 +08:00   ❤️ 2
    写 perl 很多年了。。perl 现在实战的价值就是所谓 one-liner。。谁写的更精简谁就更好,不管可读性。。这也是 perl 同 python 等其他“更高级”的语言的一个优势吧。。有点像所谓降维打击哈哈哈

    (不要学 perl 了,浪费时间)
    congeec
        27
    congeec  
       2018-12-06 01:15:00 +08:00   ❤️ 1
    #23 说的对
    我都复制下来,放 excel 里
    写正则还要查一会儿语法
    Tony042
        28
    Tony042  
       2018-12-06 02:41:48 +08:00
    @congeec 放 excel 里怎么实现呢,能大概讲讲吗
    thedrwu
        29
    thedrwu  
       2018-12-06 03:00:14 +08:00 via Android
    perl 作为主力脚本语言十多年,自从因为 numpy 用了 Python,发现回不去 perl 了:
    连 foreach 都不会写了,
    哪些操作会影响$_也忘了。
    嗯?这里的引用要套几层?
    从前的我怎么到处都在用 qw,那是干啥的现在怎么想不起来了…
    重新学 perl 好麻烦,还是退回 bash+sed+awk 算了。
    congeec
        30
    congeec  
       2018-12-06 03:04:48 +08:00
    @Tony042 假设你用 mac, 用 pbcopy/pbpaste 来复制粘贴。windows 也有类似的工具,不过你要自己找
    tips:column 是个很好用的表格格式化命令
    zxcvsh
        31
    zxcvsh  
       2018-12-06 07:55:14 +08:00 via iPhone
    @ToT 你怎么会想到用 pandas 的
    Mithrandir
        32
    Mithrandir  
       2018-12-06 09:07:54 +08:00
    为啥不用 python,或者 awk + sed + python -c
    swordne
        33
    swordne  
       2018-12-06 09:40:11 +08:00
    为啥我觉得这东西在 excel 里就能完成了?
    bellucci1964
        34
    bellucci1964  
       2018-12-06 09:56:48 +08:00
    说 python 就算了,说 excel 的又是什么鬼,ssh 到远程主机上哪来的 excel
    julypanda
        35
    julypanda  
       2018-12-06 10:01:26 +08:00
    不会发图,手动表情
    “这就是强者的世界吗?”
    hujianxin
        36
    hujianxin  
    OP
       2018-12-06 10:15:32 +08:00
    不会发图,手动表情
    “ talk is cheap, show me your code or excel picture ”
    thecon
        37
    thecon  
       2018-12-06 10:38:52 +08:00
    正解,oneliner 目前还没有什么能比 perl 更趁手的吧
    bucuoo
        38
    bucuoo  
       2018-12-06 10:40:33 +08:00
    awk 版本
    awk '{gsub(/[[:digit:]]+/,"&=",$1); split($1,aa,"="); split($2,na,"[=:,]"); split($4,va,"="); print aa[2]aa[1]" "na[3]" "va[2]}' a.txt
    hujianxin
        39
    hujianxin  
    OP
       2018-12-06 10:42:15 +08:00
    @thedrwu 老哥,都用了 9 年了,这么快就忘了啊
    hujianxin
        40
    hujianxin  
    OP
       2018-12-06 10:46:57 +08:00
    @thecon
    简单的任务,awk 更简洁,输入的字符更少,比如我需要看 nginx 日志里面的服务器错误的 log,只需要:awk '$4>=500'。
    但是复杂点的任务,比如我题目中提到的,perl 又更简洁很多,毕竟提供了功能强大的函数。
    如果再复杂的任务,谁还用 oneliner 啊,哈哈
    hujianxin
        41
    hujianxin  
    OP
       2018-12-06 10:48:17 +08:00
    @bucuoo
    qinrui
        42
    qinrui  
       2018-12-06 10:53:33 +08:00
    反转是什么鬼?为什么要反转
    zjsxwc
        43
    zjsxwc  
       2018-12-06 11:32:50 +08:00
    operawang
        44
    operawang  
       2018-12-06 11:36:28 +08:00
    文本处理当然是 Perl 当家
    jjianwen68
        45
    jjianwen68  
       2018-12-06 11:40:43 +08:00
    写不来这么复杂的 shell
    xiaket
        46
    xiaket  
       2018-12-06 11:46:11 +08:00
    ```{~}cat a.txt | python3 -c "import sys; \
    > seg1 = lambda line: ''.join(reversed(line.split()[0])); \
    > seg2 = lambda line: line.split()[1].split(':')[1].rstrip(','); \
    > seg3 = lambda line: line.split()[-1].split('=')[-1]; \
    > print(''.join(' '.join([seg1(line), seg2(line), seg3(line), '\n']) for line in sys.stdin.readlines()))"```

    好吧, 这么纠结的需求要放进一行,Python 的效果也一般.
    msg7086
        47
    msg7086  
       2018-12-06 13:19:08 +08:00
    喜欢 Perl 处理文本的可以试试 Ruby ……
    buhi
        48
    buhi  
       2018-12-06 13:49:24 +08:00
    真的是把 shell 这坨狗屎当成宝了...
    ecmascript2020
        49
    ecmascript2020  
       2018-12-06 14:38:18 +08:00
    用 javascript
    xingheng
        50
    xingheng  
       2018-12-06 15:47:09 +08:00
    @buhi 头一次看到有人讽刺 shell 是一坨屎的
    xingheng
        51
    xingheng  
       2018-12-06 15:56:07 +08:00
    用 awk 和 shell 可以实现:

    先分片,找到所有期望的元素:
    awk -F '[[:space:]]+|:|,|=' '{ print $1" "$4" "$10 }'

    然后用 rev 实现反转:
    awk '{ system("echo $(echo "$1" | rev) " ); }'

    拼起来:
    awk -F '[[:space:]]+|:|,|=' '{ system("echo $(echo "$1" | rev) " $4" "$10); }'

    看了一下我的环境,rev 是 BSD 的命令,Linux 和 macOS 都内置
    no1xsyzy
        52
    no1xsyzy  
       2018-12-06 15:57:59 +08:00
    @xingheng 那么你见得少了,shell 作为编程语言确实是一坨屎
    脑子混乱根本不知道自己在干什么的感觉
    shell 就只是个壳罢了。
    如果不需要调用其他程序我一般还是 python 的。
    hujianxin
        53
    hujianxin  
    OP
       2018-12-06 16:01:05 +08:00
    @no1xsyzy 这个可能是与智商有关系把,我用 shell 很顺手,脑子也很清晰
    buhi
        54
    buhi  
       2018-12-06 16:01:39 +08:00
    shell 从各方面来说作为一个编程语言都是不合格的, 任何正常的编程语言, 包括被人当成梗鄙视的 php, 都能吊打 shell 七条街, 这个就是屎的定义
    hujianxin
        55
    hujianxin  
    OP
       2018-12-06 16:02:31 +08:00
    @xingheng 很赞,学习了
    Vegetable
        56
    Vegetable  
       2018-12-06 16:02:32 +08:00
    工具是在进步的吧,没必要虐待自己不是?
    hujianxin
        57
    hujianxin  
    OP
       2018-12-06 16:03:23 +08:00
    @buhi 来来,用你先进的工具完成以下题目的问题如何?
    hujianxin
        58
    hujianxin  
    OP
       2018-12-06 16:05:40 +08:00   ❤️ 1
    @buhi 并没有题目中有提 shell 语言吗?提的时 awk、sed、perl。你是不是想喷人想疯了?搞一个假想敌就开始喷
    araraloren
        59
    araraloren  
       2018-12-06 16:10:48 +08:00
    cat **FILE** | perl6 -ne '/ ^ (.*?) \s+ .* \:(\w+) .* "value=" (\d+) $/; say ($0.comb.reverse.join, $1, $2).join("\t")'
    你可以一行行的处理,perl 同理。。
    MarioLuisGarcia
        60
    MarioLuisGarcia  
       2018-12-06 16:14:35 +08:00
    vim macro
    hawhaw
        61
    hawhaw  
       2018-12-06 16:38:06 +08:00
    perl 还是太老了
    但这货实在是强大
    几乎啥场景都能找到包
    直接用
    urmyfaith
        62
    urmyfaith  
       2018-12-06 16:47:29 +08:00
    ![]( )

    你们要到 Excel
    ltux
        63
    ltux  
       2018-12-06 16:49:57 +08:00
    这种问题本来就是 Perl 的强项,awk sed 之类的工具本来压根本就不用学,一门 Perl 走天下即可。 上面说写了后来看不懂的,你写 sed awk 过几天照样看不懂。
    hujianxin
        64
    hujianxin  
    OP
       2018-12-06 16:52:17 +08:00
    loopfor
        65
    loopfor  
       2018-12-06 16:53:58 +08:00
    我觉得这种还是 java/c#/c++顺手。
    那些一两行的看似精简,但是可维护性可读性都很差呀,出点问题调试也很麻烦。
    araraloren
        66
    araraloren  
       2018-12-06 17:04:56 +08:00
    @loopfor 但是不是所有东西都需要维护的。。这东西就是用完就扔,下次再写
    yiyizym
        67
    yiyizym  
       2018-12-06 17:20:00 +08:00
    用 awk,自定义一个反转函数:rev

    awk 'function rev(str){if(str == "") return ""; else return (rev(substr(str,2)) substr(str,1,1))} {print rev($1), substr($2,8), substr($4,7)}' a.txt
    hujianxin
        68
    hujianxin  
    OP
       2018-12-06 17:30:59 +08:00
    @yiyizym 可惜 awk 没有自带一个这种函数
    yiyizym
        69
    yiyizym  
       2018-12-06 17:32:12 +08:00
    @yiyizym

    第二列多了个逗号,而且把 fed 也算进去了,更正一下:
    awk 'function rev(str){if(str == "") return ""; else return (rev(substr(str,2)) substr(str,1,1))} {print rev($1), gensub(/[^0-9]/,"","g",$2), substr($4,7)}' a.txt
    hellolleh
        70
    hellolleh  
       2018-12-06 18:00:10 +08:00
    why not python?
    lululau
        71
    lululau  
       2018-12-06 18:17:22 +08:00   ❤️ 2
    说 Python 的可以试试能不能一分钟之内写出代码来,是的,像这样的不太复杂的文本处理任务用 Perl 一分钟之内就可以写出来代码

    说 Excel 的可以试试算个一千万行或者更大的文本试试?

    Perl 相比 sed / awk 的优势是,你不许区分 perl 还是 gperl,不许记哪些选项和功能是只有 GNU 版本的才有,不需要去区分 basic regex, extended regex, posix regex,你只要会 Perl 正则就可以了

    sed 算是门艺术,偶尔写一下可以陶冶情操,贴一个 sed 实现 rev 的代码,陶冶一下😀

    sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'
    hujianxin
        72
    hujianxin  
    OP
       2018-12-06 18:25:14 +08:00
    @lululau 这个很陶冶情操,手工再见
    Raymon111111
        73
    Raymon111111  
       2018-12-06 18:52:02 +08:00
    哎呀 java 也可以其实(手动斜眼
    no1xsyzy
        74
    no1xsyzy  
       2018-12-06 19:24:40 +08:00   ❤️ 1
    @hujianxin “脑子混乱”并不是指我,而是写出 shell 的人。
    一会想要以简短的字符表明一个意思,比如$+一个字符的那些(这不查那大部头 manual 根本不知道意思);
    一会又不允许简洁地表达,比如单引号的处理(如何在单引号的引用字符串内放一个单引号?先结束前一段单引号字符串,反斜杠转义一个单引号进去,再开启下一段单引号字符,1->4 比反引号地狱还快)。

    这纯是由于 shell 根本不是固定的一个人写的,甚至不是为了同一个目的设计的特性。
    毫无主见地随波逐流地写特性出来。
    只因为“之前有这个特性所以我们还是要保留这个特性”。
    向后兼容只会造成过去的麻烦依旧堆积在那边。
    hujianxin
        75
    hujianxin  
    OP
       2018-12-06 19:27:01 +08:00
    @no1xsyzy oneliner 的话,没有这种问题,因为它根本不需要维护,用完就扔了
    no1xsyzy
        76
    no1xsyzy  
       2018-12-06 19:32:35 +08:00
    @lululau ……能,连 re 都不用
    x=input()之后用 split 爆,一行内分别是
    ''.join(reversed(x.split(" ")[0]))
    x.split("name=S:")[1].split(",")[0]
    x.split(", value=")[-1]
    用 print 输出
    然后因为任意多行的要求,整个框在 while True 里面
    总共写了 40 多秒
    no1xsyzy
        77
    no1xsyzy  
       2018-12-06 19:34:24 +08:00
    @hujianxin 那就不是“ shell 作为编程语言”的情况
    shell 的 oneliner 并不能处理什么东西
    zhuangjia
        78
    zhuangjia  
       2018-12-06 20:14:53 +08:00
    @xingheng 学习了
    shyrock
        79
    shyrock  
       2018-12-06 20:21:18 +08:00
    @lululau emmm。。。这比较方法。。。是 m20p 比冰箱的显示分辨率高的比法?
    Kirscheis
        80
    Kirscheis  
       2018-12-06 20:27:02 +08:00   ❤️ 1
    import re

    n = re.compile(r'''name=S:(.{3})''')
    m = re.compile(r'''value=(\d*)''')

    with open('asdf','r') as f:
    s = f.readlines()

    for i in s:
    a,b,c,d = i.split()
    a = a[::-1]
    b = n.match(b).groups()[0]
    d = m.match(d).groups()[0]
    print(a, b ,d)


    python,写了 30 秒左右吧。

    不是说 perl 这些不好,我个人认为新的这些脚本语言的一个优点是,即使没有接触过编程的人,也能大概猜出来它想干什么,因此在过些年过气之后,不至于让大家都觉得遗留的脚本是天书。
    aliipay
        81
    aliipay  
       2018-12-06 20:53:21 +08:00
    @shyrock 差不多吧,所以正确方法应该是选取一个合适的工具。
    lululau
        82
    lululau  
       2018-12-06 21:27:02 +08:00 via iPhone
    学开汽车比学开飞机容易,所以汽车比飞机好,见识短没关系,但是保持开放的心态,先了解再判断
    no1xsyzy
        83
    no1xsyzy  
       2018-12-06 22:44:37 +08:00
    @Kirscheis 不至于让大家都觉得遗留的脚本是天书+1
    这就是我为什么会反对 python 里加 “:=”
    ps1aniuge
        84
    ps1aniuge  
       2018-12-07 13:53:42 +08:00
    #建议保存编码为:bom 头 + utf8

    $输入文件 = 'a:\pscode\TEMP_2018\temp207\aaa.txt'
    $输出文件 = 'a:\pscode\TEMP_2018\temp207\aaa2.txt'

    function 翻转函数($a)
    {
    $b = $a.tochararray()
    [System.Array]::Reverse($b)
    [string]$c = [system.String]::Concat($b)
    return $c
    }

    $所有行 = Get-Content -LiteralPath $输入文件 -ReadCount 0
    $输出的所有行 = @()
    foreach ($行 in $所有行)
    {
    $列 = $行.split(' ',[System.StringSplitOptions]::RemoveEmptyEntries)
    $列 1 = 翻转函数 $列[0]
    $列 2 = $列[1].replace('name=S:','').trimend(',')
    $列 3 = $列[3].replace('value=','')
    $新列 = $列 1,$列 2,$列 3 -join ' '
    $输出的所有行 += $新列
    }
    Set-Content -LiteralPath $输出文件 -Encoding UTF8 -Value $输出的所有行

    powrshell 代码,win,linux 通用。
    源文件不要有尾部空行。
    测试通过。
    ps1aniuge
        85
    ps1aniuge  
       2018-12-07 13:56:48 +08:00
    $列 3 被 V2EX 人为分词了,不怪我
    ps1aniuge
        86
    ps1aniuge  
       2018-12-07 14:44:43 +08:00
    用法:
    在 linux 的 bash 中,用我分享的 powershell 脚本的方法:(需要先安装 linux 版 powershell )
    /usr/bin/pwsh -f "fz 翻转字符串.ps1" -输入字符串 'abcd'



    #建议保存编码为:bom 头 + utf8
    param
    (
    [string]$输入字符串
    )

    $b = $输入字符串.tochararray()
    [System.Array]::Reverse($b)
    $c = [system.String]::Concat($b)
    return $c
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5552 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 02:39 · PVG 10:39 · LAX 18:39 · JFK 21:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.