2

私の bash スクリプトのヘッダーで、ユーザー名と IP アドレスを要求する必要があります。

この方法でエントリを検証する必要があります。

  • nameユーザー名は、スペースをアンダースコアに置き換えた変数に格納する必要があります。サンプルの場合、ユーザーがヒットした場合、変数"Albert Smith"に格納する必要があります。"Albert_Smith"name
  • IP アドレスについては、IP アドレスが形式と一致しているかどうかを知る必要があります。形式が適切でない場合は、エラーを報告し、適切な IP アドレスを入力して操作を続行するようユーザーに促す必要があります。

「読み取り」を使用する必要があることはわかっていますが、短いスクリプト (置き換えて検証) を理解する方法がわかりません。少し早いですがお礼を :)

4

6 に答える 6

7

さらに別の方法。バッシュのみ:

#!/bin/bash

read name
name=${name// /_}

read ip
if [[ "$ip" =~ ^([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})$ ]]
then
    for (( i=1; i<${#BASH_REMATCH[@]}; ++i ))
    do
      (( ${BASH_REMATCH[$i]} <= 255 )) || { echo "bad ip" >&2; exit 1; }
    done
else
      echo "bad ip" >&2
      exit 1;
fi

echo "name:$name"
echo "ip:$ip"
于 2012-10-22T17:35:59.843 に答える
5

not exactly the answer to the question, but for those who love "one liners", an IP validating regex:

[[ "$IP" =~ ^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$ ]] && echo "valid" || echo "invalid"
于 2014-07-02T11:58:20.503 に答える
3

最初の部分はtrで、2 番目の部分は と でgrep実行できawkます。

#!/bin/sh

echo "Enter a name:"
read FULL_NAME

FULL_NAME_REPLACED="$(echo $FULL_NAME | tr ' ' _)"
echo $FULL_NAME_REPLACED

echo "Enter an IP address:"
read IP_ADDRESS

if echo "$IP_ADDRESS" | egrep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
then
    # Then the format looks right - check that each octect is less
    # than or equal to 255:
    VALID_IP_ADDRESS="$(echo $IP_ADDRESS | awk -F'.' '$1 <=255 && $2 <= 255 && $3 <= 255 && $4 <= 255')"
    if [ -z "$VALID_IP_ADDRESS" ]
    then
        echo "The IP address wasn't valid; octets must be less than 256"
    else
        echo "The IP address was valid"
    fi
else
    echo "The IP address was malformed"
fi

このスレッドawkで使用されている表現が見つかった場合。これはorを単独で使用する場合の改善点であり、.grepsed400.400.400.400

于 2012-10-22T16:23:44.027 に答える
1

エントリは行ベースになると思います (つまり、名前が最初の行になり、IP が 2 番目の行になります)。あなたはこれを行うことができます:

#!/bin/bash

read name    
while [[ ! "$name" =~ '[A-Za-z ]' ]]; do
    read -p "Wrong name format. Re-enter: " name
done

name="${name// /_}"

read ip
while [[ ! "$ip" =~ '^((25[0-5]|2[0-4][0-9]|[01][0-9][0-9]|[0-9]{1,2})[.]){3}(25[0-5]|2[0-4][0-9]|[01][0-9][0-9]|[0-9]{1,2})$' ]]; do
    read -p "Not an IP. Re-enter: " ip
done

IP 正規表現はかなり複雑ですが、次のように分解できます。

  1. 文字列の先頭の後に、「オクテット」の 3 つのグループに続いてピリオドが続き、その後に別の「オクテット」と文字列の終わりが続く必要があります。
  2. オクテットはどちらか
    1. 250-255、
    2. 200-249
    3. 100 から 199 (000 から 099 を含み、数値の前に明示的な 0 がある)
    4. 1 桁または 2 桁 (つまり、0 ~ 99)

ループ フォームは!の結果を無効にするため、コマンドが失敗しgrepている間もループし続けます。に変数を渡すためにgrep使用します。2 番目のフラグを使用すると、 OR 演算子、グループ化、繰り返しを含む拡張正規表現を使用できます。printfgrep-Egrep|(){}

これが少し役立つことを願っています=)

于 2012-10-22T16:21:19.080 に答える
0

まだ新しいバージョン

関数として:

ask4nameIp() {
    unset ip name
    local var v1 v2 v3 v4
    while ! [ "$name" ] || ! [ "$ip" ]; do
        printf "Name: %s\r" $name
        read -p Name:\  var
        [ "$var" ] && name=${var// /_}
        printf "IP: %s\r" $ip
        IFS=. read -p IP:\  v{1..5}
        ((${#v1}*${#v2}*${#v3}*${#v4})) &&
            [ -z "${v1//[0-9]}${v2//[0-9]}${v3//[0-9]}${v4//[0-9]}$v5" ] &&
            ((0<=v1&&v1<=255&&0<=v2&&v2<=255&&0<=v3&&v3<=255&&0<=v4&&v4<=255)) &&
           ip=$v1.$v2.$v3.$v4
        [ "$name" ] && [ "$ip" ] ||
            echo something wrong: ${name:-name missing} ${ip:-ip missing}...;
    done;
    printf "Name: '%s'\nIP:   '%s'\n" $name $ip
}

変数$nameであり$ip、関数の外で使用できます:

$ ask4nameIp ; declare -p name ip
Name: foo bar 23
IP: 10.123.45.67
Name: 'foo_bar_23'
IP:   '10.123.45.67'
declare -- name="foo_bar_23"
declare -- ip="10.123.45.67"

問題がなくなるまでループする完全な手順

次のようなもの: (完全な bash ! パイプなし、外部 tr、awk、sed なし ...) スクリプト ファイルに書き込む必要なく、bash コンソールでカット アンド パストを使用してテストできます。

unset name ip; \
while ! [ "$name" ] || ! [ "$ip" ];do
    printf "Name: %s\r" $name;
    read -p Name:\  var;
    [ "$var" ] && name=${var// /_};
    printf "IP: %s\r" $ip;
    read -p IP:\  var;
    iparray=($( IFS=".";echo $var;));
    [ ${#iparray[@]} -eq 4 ] && \
        [ $iparray -ge 0 ] && [ $iparray -le 255 ] && \
        [ ${iparray[1]} -ge 0 ] && [ ${iparray[1]} -le 255 ] && \
        [ ${iparray[2]} -ge 0 ] && [ ${iparray[2]} -le 255 ] && \
        [ ${iparray[3]} -ge 0 ] && [ ${iparray[3]} -le 255 ] && \
        ip=$var;
    [ "$name" ] && [ "$ip" ] || echo something wrong...;
  done; \
printf "Name: '%s'\nIP:   '%s'\n" $name $ip

これは、bash の正規表現を使用するよりも強力に見えますが、実際に使用すると、はるかに軽量です。

使用中、これにより、すでに定義されている変数をデフォルトとしてすべてのリクエストが表示され、すべての変数が定義されるまでループします。

  1. unset必要なすべての変数
  2. 必要なすべての変数が定義されるまでのメインループ
  3. printrequest とすでに定義されている変数 (デフォルトとして\r) を使用し、代わりに使用して同じ行にとどまります\n
  4. プロンプト要求とread回答用 (要求は、同じ場所で、前の行でプロンプトが表示されたものに上書きされます)。
  5. スペースをアンダースコアに置き換え、name何かがあるかどうかを定義します
  6. プロンプト リクエストとanserよりも、name変数:リクエスト + 定義済みの操作を繰り返します。printread
  7. IP の整数を分割するために一時配列を使用する iparray
  8. チェック: 整数の数 == 4 で、すべてが 0 から 255 までの整数である場合、 を割り当てIPます。
  9. echoすべての変数が定義されていない場合、エラー メッセージが表示されます。
  10. ループ
  11. 結果を印刷する

アニメーションデモ

于 2012-10-22T16:44:41.887 に答える