【问题标题】:Fortune with -m exclude string财富与 -m 排除字符串
【发布时间】:2016-02-18 02:29:06
【问题描述】:

我尝试在 CentOS 7 上使用 fortune-mod 版本 9708 来仅显示 oneliners。所以我需要防止在第二行显示作者的命运。 所以这个财富是我不想看到的:

> fortune -s -n 65
Whip me.  Beat me.  Make me maintain AIX.
        -- Stephan Zielinski

作为测试,我尝试了“邪恶”。这是所有包含邪恶的命运的结果:

> fortune -s -n 65 -m Evil
(bofh-excuses)
%
Evil dogs hypnotized the night shift
%
(paradoxum)
%
  Evil isn't all bad.
%

那么,我如何才能获得不含“邪恶”的财富。 我试过了:

> fortune -s -n 65 -m ((?!Evil).)*
> fortune -s -n 65 -m ((?\!Evil).)*
> fortune -s -n 65 -m "((?!Evil).)*"
> fortune -s -n 65 -m '((?!Evil).)*'

还有更多组合。用一个 !打破命令。逃避它似乎不起作用。任何提示如何实现这一点?

【问题讨论】:

  • 您需要引用您的模式,或者您的模式由 bash 解释,而不是作为命令行参数传递。另外,我不确定 pcre 是否被理解(很可能不是)。
  • Als 尝试使用引号(已编辑问题)
  • 啊,好吧,没有pcre绝对没有排除字符串的方法?
  • 如果我们在这里谈论 BRE/ERE,那么就没有负面的前瞻/后瞻。但是,您不能编写一个使用while 循环的函数包装器来获得没有Evil(或任何模式,就此而言)的格言吗?
  • 好吧,如果没有其他办法,我想我可以。感谢您的帮助!

标签: regex bash scripting escaping


【解决方案1】:

循环直到你找到一笔财富:

while fortune -sn80 |awk 'END { if (NR == 1) { print; exit 1 } }'; do true; done

while 循环将继续运行,直到awk 以非零值退出,这仅在我们找到单线时才会发生。 awk 代码读取全部数据,然后在最后检查记录数(NR,行数)是否为 1。如果是这样,打印最后(唯一的)行并退出while 循环。

我假设您已使用-n 65 来限制大小,因此我将其扩展为 80。显然,您可以将其删除,将其恢复为 65,或将其更改为您认为合适的其他值。


这是一个接受单行引号(带有第二行属性)并打印在一行上的变体:

while fortune -sn80 |awk '
  NR == 1 { L = $0 }
  NR == 2 && $1 == "--" { NR--; $1 = " --"; $0 = L $0 }
  END { if (NR == 1) { print; exit 1 } }
'; do true; done

这增加了两个条件。首先,我们跟踪第 1 行的内容。其次,如果第 2 行有 -- 作为其第一个以空格分隔的内容,则减少行数并将前导空格替换为单个空格(更改 $1 导致 $0 为被重新间隔),并在前一行前面加上最后一个子句只看到一行。

例如这段话:

Don't Worry, Be Happy.
                -- Meher Baba

现在接受后成为:

Don't Worry, Be Happy. -- Meher Baba

排除Evil(崇高的追求?):

while fortune -sn80 |awk '
  END { if (NR == 1 && !index($0, "Evil")) { print; exit 1 } }
'; do true; done

我所做的只是说在最终条件下没有“邪恶”的索引。您可以使用扩展的正则表达式代替(NR == 1 && ! /Evil/),尽管请注意awk 正则表达式不允许数字量词(所以/a+/ 很好,但/a{1,}//a{1,9}/ 将不起作用)。如果你想不区分大小写,你必须做tolower($0) !~ /evil/

【讨论】:

  • 谢谢,我会试试这个。可能需要一些时间。我的目标是将其集成到我的 MotD 生成器中:outsideit.net/generate-motd
【解决方案2】:

这是运行 fortune 直到它产生单行输出的想法的变体:

while fortune=$(fortune -sn80) ; [[ $fortune == *$'\n'* ]] ; do : ; done

它循环直到输出不包含内部换行符。那么单行输出在fortune变量中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-08
    • 2020-03-10
    相关资源
    最近更新 更多