首页 > 解决方案 > bash 两个 if 条件中的脚本并在 for 循环中打印

问题描述

您好,我正在学习用 bash 编写脚本,我正在尝试解决一个小练习。练习是这样的

如果名为“basenew”的变量包含名为“valuebase”的变量的内容。“basenew”必须包含超过 113,469 个字符。如果两个条件都满足,那么脚本必须打印变量“basenew”的最后 20 个字符。

我的代码是

#!/bin/bash

basenew="8dm7KsjU28B7v621Jls"
valuebase="ERmFRMVZ0U2paTlJYTkxDZz09Cg"

for i in {1..40}
do
    basenew=$(echo $basenew | base64)

    if [[ $basenew =~ $valuebase && ${#basenew} -ge 113469 ]] ; then
        echo $i
        echo $basenew | wc -c
        StrLen=`echo ${basenew} | wc -c`
        From=`expr $StrLen - 20`
        echo $basenew | cut -c ${From}-${StrLen}
    else
        echo "error"

    fi
done

但我卡住了,因为在循环 28 中打印,并且是最后 20 个但不是正确答案。

使用 tail -c 20 打印最后 20 个字符有什么建议吗?

谢谢

标签: bashfor-loopif-statementtail

解决方案


为什么您认为 的值basenew会在循环执行期间发生变化?你永远不会分配它。但是你指定var你从不使用,这可能是问题吗?是的,您需要更新basenew,而不是未使用的var.

您的脚本还有另一个问题:cut将您的字符选择应用于输入的每一行。base64,默认情况下,将输出拆分为 76 个字符的行。所以,过了一会儿,你有很多短线。由于它们都比您的规范短得多cut,因此只会打印很多换行符,而不是字符串的最后 20 个字符。base64您可以更改with的行为,base64 -w0但它也会更改每次迭代的结果,并且您可能永远不会匹配引用字符串。

echo而不是按照cutjoop 的建议进行管道:"${basenew: -20: 20}"扩展为 的值的最后 20 个字符basenew。或者,更简单但等效:"${basenew: -20}". 不要忘记 和 之间的空格:-20它是必需的。

最后,您可以使用更多内置的 bash 结构来避免外部命令(wc, echo, cut),使用现代$(...)而不是旧的反引号,并使用算术评估(((...)))而不是过时的expr. 试试,也许:

#!/usr/bin/env bash

# file: foo.sh

basenew="8dm7KsjU28B7v621Jls"
valuebase="ERmFRMVZ0U2paTlJYTkxDZz09Cg"

for i in {1..40}; do
    basenew=$(echo "$basenew" | base64)
    if [[ $basenew =~ $valuebase ]] && (( ${#basenew} >= 113469 )) ; then
        printf '%d\n%d\n%s\n' "$i" "${#basenew}" "${basenew: -20}"
    else
        printf 'error\n'
    fi
done

演示:

$ ./foo.sh
error
...
error
28
113469
U2paTlJYTkxDZz09Cg==
error
...
error

推荐阅读