1. ホーム
  2. スクリプト・コラム
  3. リナックスシェル

シェルプログラミング。変数の高度な使い方

2022-01-05 16:07:07

変数置換

{テーブル 構文 {を使用します。 説明 {を使用します。 変数名#マッチングルール}を指定します。 変数から で始まる にマッチするルールマッチが実行されます。 最短 にマッチするデータを削除します。 変数名 ## 一致ルール}${ 変数名 ## 一致ルール 変数から で始まる にマッチするルールマッチが実行されます。 最長 にマッチするデータを削除します。 変数名%マッチングルール}を指定します。 変数から 終了 にマッチするようなルールマッチを実行します。 最短 にマッチするデータを削除します。 変数名%%マッチングルール}${変数名%%マッチングルール}。 変数から 終了 にマッチするようなルールマッチを実行します。 最長 にマッチするデータを削除します。 変数名/古い文字列/新しい文字列}を指定します。 変数の内容が文字列と一致する場合は 最初の 古い文字列は、新しい文字列に置き換えられます 変数名//古い文字列/新しい文字列}を指定します。 変数の内容が文字列と一致する場合は すべて 古い文字列は新しい文字列に置き換わります


var1="hello world hello world"
# The longest and shortest are actually the greedy and non-greedy patterns in regular expressions

# delete the data with the matching rule *lo (shortest at the beginning delete)
echo ${var1#*lo}
echo ${var1#*lo} -> world hello world

# Delete data with a match rule of *lo (longest deletion at the beginning)
echo ${var1##*lo}
-> world

# Delete data with a match rule of hel* (shortest delete at the end)
echo ${var1%hel*}
-> hello world 

# Delete data with a match rule of hel* (trailing longest delete)
echo ${var1%%hel*}
->

# Replace the first old string world with Beijing
echo ${var1/world/Beijing}
-> hello Beijing hello world

# Replace the first old string world with Beijing
echo ${var1/world/Beijing}
->hello Beijing hello Beijing


変数テスト

{テーブル 変数置換法 変数yが設定されていない 変数yがNULL 変数yに値が設定される x=${y-new-value} とする。 x=新しい値 {を使用します。 xは空 x=$y x=${y:-new value}となります。 x=新しい値 {を使用します。 x 新値 x=$y x=${y+new value}とする。 xは空 x=新しい値 x=新しい値 x=${y:+new value}とする。 xは空 xは空 x=新しい値 x=${y=new value}とする。 x=新しい値 {を使用します。 xは空 x=$y y=新しい値 {を使用します。 yの値は変更されません {を使用します。 y 値は変更なし x=${y:=new value} となります。 x=新しい値 x=新しい値 x=$y y=新しい値 y=新しい値 {を使用します。 yの値は変更されません x=${y?新値}とする。 新しい値が標準エラー出力(画面)に出力される xは空 x=$y x=${y:?新値}とする。 新しい値は、標準エラー出力に出力されます 標準エラー出力に出力された新しい値 {を使用します。 x=$y

  • 中括弧の中に「:」がない場合は、変数yは空か設定されていないことになり、別の処理をする。中括弧の中に「:」がある場合は、変数y
  • は、空でも設定されていなくても同じように扱われます。 {を使用します。
  • 中括弧が "-" または "+" の場合,変数 x の値を変更しても,変数 y の値は変更されない
  • 中括弧の中に "=" がある場合、変数 x の値を変更すると、変数 y の値も変更されます。
  • 中括弧が"? "の場合、変数yが存在しないか空のときは、「新しい値」をエラーとして画面に出力します。


# x=${y-new-value}
echo ${y=$var1}
->hello world hello world

y=
echo ${y-$var1}
->

y=hello Beijing
echo ${y-$var1}
-> hello Beijing

# x=${y:-new value}
echo ${y:-$var1}
->hello world hello world

y=
echo ${y:-$var1}
->hello world hello world

y=hello Beijing
echo ${y:-$var1}
->hello Beijing

# x=${y+new value}
echo ${y+$var1}
->

y=
echo ${y+$var1}
-> hello world hello world

y=hello Beijing
echo ${y+var1}
->hello world hello world

# x=${y:+new value}
echo ${y:+$var1}
->

y=
echo ${y:+$var1}
->

y=hello Beijing
echo ${y:+var1}
-> hello world hello world

# x=${y=new value}
x=${y=$var1}
echo $x
->hello world hello world
echo $y
->hello world hello world

y=
x=${y=$var1}
echo $x
->
echo $y
->

y=hello Beijing
x=${y=$var1}
echo $x
-> hello world hello world
echo $y
->hello Beijing

# x=${y:=new value}
x=${y:=$var1}
echo $x
->hello world hello world
echo $y
->hello world hello world

y=
x=${y:=$var1}
echo $x
->hello world hello world
echo $y
->hello world hello world

y=hello Beijing
x=${y:=$var1}
echo $x
->hello Beijing
echo $y
->hello Beijing

# x=${y?new value}
echo ${y?$var1}
->-bash: y: hello world hello world

y=
echo ${y?$var1}
->

y=hello Beijing
echo ${y?$var1}
-> hello Beijing

# x=${y:? new value}
echo ${y?$var1}
->-bash: y: hello world hello world

y=
echo ${y:? $var1}
->-bash: y: hello world hello world

y=hello Beijing
echo ${y:? $var1}
->hello Beijing


 これを読んでもまだ思い出せない! 上の表を参考にしてください

文字列処理

文字列の長さ

{テーブル 構文 {を使用します。 {を使用します。 説明 {を使用します。 {を使用します。 方法I 文字列 {を使用します。 なし 方法2 expr length "$string" 文字列にスペースがある場合は、二重引用符で囲む必要があります。


# Method 1
var1="hello world"
echo ${#var1}
->11

# Method two
len=`expr length "$var1"`
echo $len
->11

## var1 has spaces, must add double quotes, otherwise error is reported
expr: syntax error

## var2 has no spaces, you don't need to add double quotes
var2=hello
expr length $var2
5


サブストリング文字インデックス

{テーブル 構文 expr インデックス $string $substring {を使用します。 文字列内にスペースがある場合は、文字列/部分文字列を二重引用符で囲む必要があります。 このメソッドは部分文字列のインデックス位置を見つけるのではなく、部分文字列を文字に分割して、最初に見つかった文字のインデックス位置を返します。そしてインデックスは 1 から始まります。

expr index "$var1" llo
->3

expr index "$var1" lole
->2

サブストリングの長さ

{テーブル 構文 expr match $string サブストリング {を使用します。 文字列内にスペースがある場合は、文字列/部分文字列を二重引用符で囲む必要があります。

expr match "$var1" hel
->3

expr match "$var1" llo
->0

expr match $string 部分文字列の長さを取得するには、先頭からマッチさせなければなりません。

部分文字列の抽出

{テーブル 構文 {を使用します。 {を使用します。 説明 {を使用します。 {を使用します。 方法I 文字列:位置}を指定します。 {を使用します。 文字列中の位置から始まる部分文字列を抽出する。 方法2 文字列:位置:長さ}を指定します。 {を使用します。 文字列の位置から始まる長さの部分文字列を抽出します。 {を使用します。 方法3 文字列: -位置}を指定します。 (-positionの前のスペースに注意) 位置の末尾から部分文字列を抽出する 方法4 文字列:(位置)}. {を使用します。 文字列の先頭から始まる位置から部分文字列を抽出する 方法5 {を使用します。 expr substr $string $position $length {を使用します。 文字列の位置から始まる長さの部分文字列を抽出します。 {を使用します。


# Method 1
echo ${var1:2}
->llo world

# Method two
echo ${var1:2:5}
->llo w

# Method three
echo ${var1: -2}
->ldo

echo ${var1: -2:1}
->l

# Method four
echo ${var1:(3)}
->lo world

echo ${var1:(3):2}
->lo

echo ${var1:(-2):1}
->l

# Method 5
expr substr "$var1" 2 5
->ello

注:expr substr $string $position $length は位置が1から始まり、${string:position:length}は0から始まる。

var2=hello
echo ${var2:2:5}
->llo

expr substr $var2 2 5
->llo


ちょっとやってみる

      要件の説明 変数string="ビッグデータ処理フレームワークはHadoopであり、Hadoopはオープンソースプロジェクトである。" スクリプト実行後、変数stringをプリントアウトし、以下のオプションをユーザに与える。

    {を使用します。 文字列の長さを表示
  • 文字列からすべてのHadoopを削除する
  • {を使用します。 最初のHadoopをMapreduceに置き換える
  • すべてのHadoopをMapreduceに置き換える {を使用します。

      ユーザーが1|2|3|4の数字を入力すると対応する項目の機能を実行し、q|Qを入力すると対話型モードを終了します。

#! /bin
string="Bigdata process framework is Hadoop,Hadoop is an open source project."


function print_tips
{
 echo "=============================="
 echo "1->Print string length"
 echo "2->Delete all Hadoop" in string;
 echo "3->Replace the first Hadoop with Mapreduce"
 echo "4->Replace all Hadoops as Mapreduce"
 echo "q|Q->Quit"
 echo "=============================="
}

function len_of_string
{
 echo "${#string}"
}

function del_hadoop
{
 echo "${string//Hadoop/}"
}

function rep_first_hadoop_mapreduce
{
 echo "${string/Hadoop/Mapreduce}"
}

function rep_all_hadoop_mapreduce
{
 echo "${string//Hadoop/Mapreduce}"
}
while true
do
 echo ""
        echo ""
        echo ""
        echo ""
 echo "[string=$string]"
 print_tips
 read -p "Please input your choice (1|2|3|4|q|Q):" choice
 case $choice in
  1)len_of_string;;
  2)del_hadoop;;
  3)rep_first_hadoop_mapreduce;;
  4)rep_all_hadoop_mapreduce;;
  q|Q)exit;;
  *)echo "Error input,only in (1|2|3|4|q|Q)";;
 esac
done

コマンド交換

      シェルのコマンド代入とは、コマンドの出力を変数に代入することです。例えば、あるディレクトリで ls と入力すると、カレントディレクトリにあるすべてのファイルを見ることができますが、その出力をどのように変数に格納するのでしょうか。そこで、シェルプログラミングで非常によく使われる機能であるコマンド代入を使う必要があるのです。

{を使用します。 方法I {を使用します。 $(コマンド) {を使用します。
構文
コマンド {を使用します。
方法2


# Get all users of the system and output
#! /bin
index=1
for user in `cat /etc/passwd | cut -d ":" -f 1`
do
 echo "This is the first $index user with the name: $user"
 index=$(($index + 1))
        # $(()) is mainly used for integer arithmetic, reference variables may or may not be preceded by $
done

# Calculate this year or next year based on system time
#! /bin
year=`date +%Y`
echo "This year is $year, next year is $(($year+1))year"

# Get how many weeks are left in the year and how many weeks have passed based on system time
#! /bin
# Calculate what day of the year it is
#! /bin
days=$(date +%j)
weeks=$((days/7))
remain_weeks=$((52-weeks))
echo "There are $remain_weeks weeks left in the year, $weeks have passed"

# Determine if the nginx process exists, and if not, pull it up automatically
#! /bin
nginx_process_num=$(ps -ef | grep nginx | grep -v grep | wc -l)
if [ $nginx_process_num -eq 0 ];then
 echo "nginx not started, pulling up in... "
 systemctl start nginx
else
 echo "nginx has started... "
fi


タイプ変数付き

      シェルプログラミングでは、変数に型を指定する必要がある場合、declareコマンドとtypesetコマンドを使用する必要があります。この2つのコマンドは等価です。(の-記号は追加するとき、+記号は削除するときに使います、例:+x)

{テーブル パラメータ {を使用します。 意味 {を使用します。 {を使用します。 -r 変数を読み取り専用に設定する -i 変数に整数を設定する -a {を使用します。 変数を配列として定義する {を使用します。 -f このスクリプトより前に定義されたすべての関数とその内容を表示する -F {を使用します。 このスクリプトより前に定義された関数の名前のみを表示する -x 環境変数として宣言する {を使用します。


# Set to read-only
var1="hello wordl"
var1="hello shell"
declare -r var1
var1="hello java"
->-bash: var1: readonly variable

# Set to shaping
num1=20
num2=$num1+30
echo $num2
->20+30 # linux default setting is string
declare -i num3
num3=$num1+30
echo $num3
->50

# Define an array
declare -a array
array=(1 2 3 4)
# Output the entire contents
echo ${array[@]} 
# Output the contents with subscript index 1
echo ${array[1]}
# The number of elements in the array
echo ${#array[@]}
# Specify the index assignment
array[0]=555
# Add elements at the end
array[4]=666
# Delete an element
# Delete the element with index 2
unset array[2]
# Clear the entire array
unset array
# Access in pieces
# Show the three elements of the array with subscript indexes starting from 1 to 3 (wrap the head and not the tail)
${array[@]:1:4}
# Array traversal
for n in ${array[@]}
do
    echo $n
done

# Show all functions defined before the script and their contents
# Add declare -f after the print_tips method that you tried before, and you'll see that only the functions and content before the command are displayed


数学演算のためのExpr

Expr演算子の比較表です。

{テーブル 演算子 {を使用します。 意味 num1|num2 {を使用します。 num1 が空でなく、かつ 0 でない場合、num1 を返し、そうでない場合、num2 を返します。 num1 & num2 num1 が空でなく、かつ 0 でない場合、num1 を返し、そうでない場合は 0 を返します。 num1 < num2 {を使用します。 num1がnum2より小さい場合は1を、それ以外の場合は0を返します。 num1 <= num2 {を使用します。 num1がnum2以下であれば1を、そうでなければ0を返します。 num1 = num2 {を使用します。 num1 と num2 が等しい場合は 1 を返し、そうでない場合は 0 を返します。 num1 ! = num2 num1 が num2 と等しくない場合は 1 を、そうでない場合は 0 を返します。 num1 > num2 {を使用します。 num1がnum2より大きい場合は1を、それ以外の場合は0を返します。 num1 >= num2 {を使用します。 num1がnum2以上であれば1を、そうでなければ0を返します。

注:これらの操作をコマンドラインで行う場合は、expr $num1 \| $num2,expr $num1 \> $num2 のようにエスケープする必要があり、そうしないとエラーが報告されます。

num1=20
num2=100
expr $num1 \| $num2
expr $num1 \& $num2
expr $num1 \< $num2
expr $num1 \<= $num2
expr $num1 \> $num2
expr $num1 \>= $num2
expr $num1 = $num2
expr $num1 ! = $num2
expr $num1 + $num2
expr $num1 - $num2
expr $num1 \* $num2
expr $num1 / $num2
expr $num1 % $num2

ビーシー

      bcはbashの組み込み演算子で、浮動小数点演算をサポートしています。デフォルトでは bc は整数に正確であり、指定した小数点以下の桁数を保持するようにスケールを設定することができる。

bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details ty