如何像bash脚本一样发财

时间:2018-10-23 11:46:04

标签: bash

所以我是bash的新手,在这种命令行模式下,我发现了很多用于财富命令行应用程序的文件作为其激励消息的来源:

Quote 1 line 1
Quote 1 line 2
%
Quote 2 line 1
Quote 2 line 2
Quote 2 line 3
%

我想知道如何制作bash脚本以随机打印那些引号。跳过随机部分,我真的很好奇,如何将每一行打印成用引号%隔开的一组引号? 谢谢

3 个答案:

答案 0 :(得分:2)

假设您在名为“ fortunes.txt”的文件中加了引号,请尝试以下纯Bash解决方案:

#! /bin/bash

declare -a fortunes=()  # Array of fortunes
declare -i curr_idx=0   # Index of fortune currently being read

while IFS= read -r line ; do
    [[ $line == '%' ]] && curr_idx+=1 || fortunes[curr_idx]+="$line"$'\n'
done < fortunes.txt

printf '%s\n' "${fortunes[RANDOM % ${#fortunes[*]}]}"

在我较旧的Linux系统上,该代码大约需要1秒钟才能运行在一个1兆字节的“ fortunes.txt”文件上。对于大得多的输入文件,这是不切实际的。

答案 1 :(得分:0)

由于互联网连接问题,我只读了@pjh和@paul hodges答案,我喜欢它们的简单性。我已经想出了一个凌乱的东西: (这不需要先读取整个文件行,而只需读取特定行)

#!/usr/bin/env bash

randqu_file=fortunes.txt

rando_line=$(( (RANDOM % $(wc -l < $randqu_file) + 1 )))

while [[ $(sed -n "${rando_line}p" $randqu_file) != '%' || $rando_line -eq $(wc -l < $randqu_file) ]]; do
    rando_line=$((rando_line - 1))
    [[ $rando_line -eq 0 ]] && break
done

rando_line=$((rando_line + 1))

while [[ $(sed -n "${rando_line}p" $randqu_file) != '%' ]]; do
    sed -n "${rando_line}p" $randqu_file
    rando_line=$((rando_line + 1))
    [[ $rando_line -gt $(wc -l < $randqu_file) ]] && break
done

答案 2 :(得分:-1)

我是白痴,我没有正确阅读要求。

一个不可移植 GNU单线(ymmv):

sed -n "$(grep -n % quoteFile|shuf|head -1|sed 's!:%!,/%/!')"' {/%/!p; /!%/p}' quoteFile

这是一个子shell,它使用grep -n % quoteFile来获取%的行号,使用shuf来对其进行随机化,使用head -1来获取经过改组的分隔符的第一个行号,以及将sed更改为5:%的{​​{1}},作为sed外部调用的范围说明符。请注意,从双引号切换到单引号,因此我不必特别对待!(我的bash仿真很讨厌)。

外面的5,/%/跳到sed的%的指定行号,并打印所有没有%的行,直到看到下一个%为止。

这样做 意味着您将需要前导%,并且应删除尾随%。

使用Perl:

shuf
  

perl -ne

-n表示读取每一行并对它执行代码,有点像awk。 -e定义输入表达式字符串(代码)

  

BEGIN {$ / = q {%}; }

在读取任何内容之前,将输入记录分隔符设置为百分号。

  

s / ^ \ n |%$ // g;

对于每条“行”,请从以前的任何定界符,a和训练百分号中去除前导换行符。

  

按@F,如果/./ ;,则$ _

如果记录中包含任何字符,则将读取的记录推入F数组中(在前导换行符之后的最后一个字符将不存在)。

  

END {打印$ F [int(rand(@F))]; }

在处理完所有记录后,随机打印一张。

所有输入将从任何提供的perl -ne 'BEGIN{ $/=q{%}; } s/^\n|%$//g; push @F, $_ if /./; END{ print $F[int(rand(@F))]; }' quoteFile

中读取

玩得开心。