【问题标题】:Bash- loop through each character in a string to check for specific patternBash-遍历字符串中的每个字符以检查特定模式
【发布时间】:2014-11-22 09:30:47
【问题描述】:

所以我需要检查字符串中的每个字符 - 输入 - 以查看它是否匹配/不匹配模式。

在 Codelish 中:

我猜我必须使用 for 循环?

在for循环里面会有-

    for each character in string
    do (the following)
    if it doesn't contain one/more number
    echo it doesn't contain contain one/more number
    fi
    [then other conditions]
    done.

所以我要做的是分析字符串中的每个字符并将错误消息(针对每个条件)显示为输出。

任何帮助将不胜感激。

【问题讨论】:

  • 一个字符怎么能包含一个或多个个数字?
  • 哎呀,我的意思是一个数字(或范围内的字母)。 “如果字符不是数字,那就做点什么。”
  • 如果您从这里开始并指出您被卡住的部分,那将会很有用。你知道如何在 bash 中编写 for 循环吗?你知道如何匹配模式吗?您是否愿意使用 awk 之类的工具来更有效地完成工作?
  • 如果您可以 1) 更明确地了解您正在寻找的这种模式,2) 向我们展示您的典型输入数据是什么样的,以及 3) 您期望的输出,这也会有所帮助。 bash(或 awk、perl 或 python)脚本逐个字符地循环字符串的效率很低。使用精心设计的正则表达式(或其他东西)一次处理整个字符串通常要好得多
  • 嗯,一般的想法是分析输入并在匹配/不匹配模式时显示消息。就像 - 如果输入是密码,它是否包含一个特殊字符?它是否包含一个/多个大写字母?如果消息包含多个特殊字符,则显示消息。具体-我正在寻找一个命令,它可以让我遍历用户输入的每个字符。

标签: regex string bash loops character


【解决方案1】:

正如我上面所说,逐个字符循环遍历字符串通常不是一种非常有效的策略。但这是一种方法,使用 awk。下面的程序确定输入文件每一行中每个字符的字符类。请参阅 awk 手册了解 character classes 的确切定义。

CharTypes0.awk

#!/usr/bin/awk -f

# Print the character class of each character in each input line
# Written by PM 2Ring 2014.10.02

BEGIN{numtypes = split("lower upper digit punct blank", types); FS = ""}

{
    for(i=1; i<=NF; i++)
        for (j=1; j<=numtypes; j++)
        {
            type = types[j]
            if ($i ~ "[[:" type ":]]")
            {
                printf "'%s': %s\n", $i, type
                break
            }
        }
}

你可以这样运行这个程序:

echo 'This is A $24 @test.' | awk -f CharTypes0.awk

输出

'T': upper
'h': lower
'i': lower
's': lower
' ': blank
'i': lower
's': lower
' ': blank
'A': upper
' ': blank
'$': punct
'2': digit
'4': digit
' ': blank
'@': punct
't': lower
'e': lower
's': lower
't': lower
'.': punct

或者您可以通过在命令行上命名它们来处理一个或多个文本文件的所有行,例如:

awk -f CharTypes0.awk test1.txt test2.txt

.....

这个程序的一个更高效的版本可以轻松地一次计算整个单词或整个行中每种类型的字符数,而不是循环遍历每个字符。


编辑

例如,

CountCharTypes0.awk

#!/usr/bin/awk -f

# Count number of characters in each input line that match various classes
# Written by PM 2Ring 2014.10.01

BEGIN{numclasses = split("lower upper alpha digit alnum punct blank", classes)}

{
    printf "\nData:[%s] Length: %d\n", $0, length($0)
    for (i=1; i<=numclasses; i++)
    {
        class = classes[i]
        printf "%s %2d\n", class, gsub("[[:" class ":]]", "&")
    }
}

CharTypes0.awk


编辑 2

这是 CharTypes 的纯 bash 版本:

#!/bin/bash

# Print the character class of each character in $1
# Written by PM 2Ring 2014.10.03
chartypes()
{
    types=(lower upper digit punct blank)

    string=$1

    for((i=0; i<${#string}; i++))    
    do
        ch=${string:i:1}
        for t in ${types[@]}
        do
            [[ $ch =~ [[:${t}:]] ]] &&
            { echo "[$ch] $t"; break; }
        done
    done
}

chartypes 'This is A $24 @test.'

【讨论】:

  • 什么是有效的策略?我只是想要一种方法来分析密码并根据规范显示消息。
  • 好吧,我可能会在 Python 中这样做。但我会在我的答案中添加更多 awk 代码,这些代码应该会给你一些想法。你觉得用 awk 写作舒服吗?
  • 嗯,这是一个作业,我们正在使用 bash。当然可以使用 awk 完成,但我们还没有介绍 awk 实用程序。因此,纯粹的 bash 方式(没有 awk)将是分析字符串输入/密码的理想选择。出于个人喜好,我会使用在 bash 下工作的任何东西,但我们还没有介绍 awk,而且有些人在不使用 awk 的情况下完成了任务。
  • 你可能已经提到过你不能使用 awk,当 Tom Fenech 提到它时,或者当我发布我的第一个示例时......但我将首先添加一个纯 bash 版本例子。
  • 好的,我想我可以用这个。我现在得到了逻辑并且可以在我的脚本中使用它。谢谢你,把它记下来作为答案。
猜你喜欢
  • 1970-01-01
  • 2010-09-09
  • 1970-01-01
  • 1970-01-01
  • 2018-07-15
  • 1970-01-01
  • 2021-01-11
  • 2015-06-17
  • 2019-10-14
相关资源
最近更新 更多