Paepoi

Paepoi » ShellScript Tips » ShellScript Tips | 文字列

ShellScript Tips | 文字列

# 最終更新日 2019.12.01

文字列の追加、抜き出し、置換
文字列は配列とは違います、追加や抜き出しは以下のようになる。
#!/bin/sh

# 変数に代入、空白等のメタ文字を含む場合はクォートで囲む
motor=スズキとカワサキ
echo $motor
#=> スズキとカワサキ

# += で文字列を合体できる
motor+=とヤマハ
echo $motor
#=> スズキとカワサキとヤマハ

# 部分抜き出しはオフセットと長さを以下のように
# 日本語も一文字として扱われる
# zsh でもこのインデックスは bash と共通になる
echo ${motor:9}
#=> ヤマハ
echo ${motor:4:4}
#=> カワサキ

# 行頭から最初と最後のパターン(ここでは'と')まで除外
echo ${motor#*と}
#=> カワサキとヤマハ
echo ${motor##*と}
#=> ヤマハ

# 行末から最初と最後のパターン(ここでは'と')まで除外
echo ${motor%と*}
#=> スズキ カワサキ
echo ${motor%%と*}
#=> スズキ

# 全てのマッチした文字列をアットマークに置換
echo ${motor//と/@}
#=> スズキ@カワサキ@ヤマハ

# 最初にマッチした文字列のみ置換
echo ${motor/と/かっこいい!}
#=> スズキかっこいい!カワサキとヤマハ

文字列への添字
#!/bin/zsh

motor=スズキカタナ

# zsh のみ
# 添字は bash では無意味な文字列になる
echo $motor[1]
# bash #=> スズキカタナ[1]
# zsh #=> ス

# カンマの後に空白を入れてはいけない
echo $motor[1,3]
#=> スズキ

# マイナスは末尾
echo $motor[-1]
#=> ナ

# 末尾からの範囲指定も可能
echo $motor[-3,-1]
#=> カタナ

# 間違った範囲指定は文字列と解釈される
echo $motor[1,2,3]
#=> スズキカタナ[1,2,3]
文字列のループ
bash の場合
#!/bin/bash

motor='スズキ カワサキ ヤマハ'

# $ISF 区切りで for 文にできる
for s in $motor; do
    echo $s
done

# $IFS は区切り文字を定義する変数
# デフォルトは スペース、タブ、改行(0xff,0x09,0x0a)
# この変数を上書きすることで区切り文字を再定義できる

__IFS=$IFS
IFS=,
csv=カンマ,区切りの,テキスト

for s in $csv; do
    echo $s
done

# 元に戻す
IFS=$__IFS
zsh の場合
#!/bin/zsh

# zsh では直書きや $@ ならば ISF 区切りを展開します
# 一度変数に入れてしまったものは展開できないので注意
for s in $@; do
    echo $s
done

motor='スズキ カワサキ ヤマハ'

# 以下のようにすれば bash 同様に展開できます
for s in ${=motor}; do
    echo $s
done

val='カンマ,区切りを,ループ'
for j in ${(ps.,.)val}; do
    echo $j
done
文字列のブレース展開
#!/bin/sh

# $IFS 区切りの文字列に展開される
echo 僕は{スズキ,カワサキ,ヤマハ}が好き
#=>僕はスズキが好き 僕はカワサキが好き 僕はヤマハが好き

# 範囲指定だと文字コード表の順番になるようだ
echo {3..6}
#=> 3 4 5 6
echo {a..g}
#=> a b c d e f g
echo {X..c}
#=> X Y Z [  ] ^ _ ` a b c

# 連番ファイルが急遽必要になった時なんかに便利
touch test_file{1..20000}.txt

文字列の大文字、小文字反転
bash の場合
#!/bin/bash

# 記号が一つなら一文字目のみ適用される

TEXT=abcDEF

echo ${TEXT^^}
#=>ABCDEF (大文字化)

echo ${TEXT,,}
#=>abcdef (小文字化)

echo ${TEXT~~}
#=>ABCdef (反転)
zsh の場合
#!/bin/zsh

TEXT=abcDEF

echo $TEXT:u
#=>ABCDEF (大文字化)

echo $TEXT:l
#=>abcdef (小文字化)
共通にしたいなら tr コマンドを使う
#!/bin/sh

TEXT=abcDEF

echo $TEXT | tr '[:lower:]' '[:upper:]' | cat
#=>ABCDEF (大文字化)

echo $TEXT | tr '[:upper:]' '[:lower:]' | cat
#=>abcdef (小文字化)

文字列中に特定文字列の存在確認
#!/bin/sh

# [[ 文字列 =~ 探したい語句 ]]
# 正規表現も使えます

mc=たしかにスズキもいいけどカワサキもかっこいいな

if [[ $mc =~ スズキ ]]; then
   echo よしお前は解っている
   [[ $mc =~ (カワサキ|ヤマハ) ]] && echo たまには浮気もいいだろう || :
   [[ $mc =~ ホンダ ]] && echo 前言撤回、帰れ || :
else
   echo 裏切り者!
fi

Copyright(C) sasakima-nao All rights reserved 2002 --- 2020.