IT・技術研修ならCTC教育サービス

サイト内検索 企業情報 サイトマップ

研修コース検索

コラム

WSLで始めるUbuntu

CTC 教育サービス

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  Microsoft Azure  Docker  Kubernetes 

第28回 bashの展開機能を知ろう(4) (宮崎悟) 2021年2月

前回は算術式展開、コマンド置換、プロセス展開について説明しました。今回は単語分割とパス展開について説明します。

単語分割

パラメータ展開、コマンド置換、算術式展開がダブルクォートで囲まれていない場合、bashはこれらを展開後に単語分割します。 シェル変数IFS が設定されていないかデフォルト値(スペース、タブ、改行)の場合、展開した結果にシェル変数IFSと同じ文字が含まれる先頭と末尾の文字列が削除され、空白1つで区切られて表示されます。

IFSが空文字列('')の場合は、単語分割されません。また、パラメータ展開、コマンド置換、算術式展開が行われない場合は単語分割されません。

パス展開

単語分割後に、bashは特殊パターン文字(*?[)が各単語に含まれていないか確認します。この特殊パターンの意味は以下のとおりです。

*

空文字列を含む任意の文字列にマッチします。シェルオプション globstar が有効である場合、**を指定するとその階層以下のディレクトリのすべてのファイルにマッチします。同様に**/が指定されると、その階層以下のすべてのディレクトリ、サブディレクトリにマッチします。

# シェルオプションglobstarがoffになっている
$ shopt globstar
globstar        off
# * は、すべてのファイルにマッチする
## ls のオプションは、1は1行ずつ表示、d はディレクトリ以下のファイルを表示しない
$  ls -1d *
abc
cf
cg
ch
def
df
dg
dh
ghi
# */ は、すべてのディレクトリにマッチする
$ ls -1d */
cf/
cg/
ch/
df/
dg/
dh/
# c* は、cから始まるすべてのファイルにマッチする
$ ls -1d c*
cf
cg
ch
# ** は * と同じ
$ ls -1d **
abc
cf
cg
ch
def
df
dg
dh
ghi
# シェルオプションglobstar をonにする
$ shopt -s globstar
$ shopt  globstar
globstar        on
# * はglobstar offと同じ
$ ls -1d *
abc
cf
cg
ch
def
df
dg
dh
ghi
# **は、すべてのファイルとサブディレクトリ以下のファイルにマッチする
$ ls -1d **
abc
cf
cf/ZEF
cf/abc
cf/def
cf/temp
cg
cg/ZEF
cg/abc
cg/def
ch
ch/ZEF
ch/abc
ch/def
ch/temp
def
df
df/ZEF
df/abc
df/def
dg
dg/ZEF
dg/abc
dg/def
dg/temp
dg/temp/temp
dh
dh/ZEF
dh/abc
dh/def
dh/temp
ghi
# **/は、すべてのディレクトリとサブディレクトリにマッチする
$ ls -1d **/
cf/
cf/ZEF/
cf/abc/
cf/def/
cf/temp/
cg/
cg/ZEF/
cg/abc/
cg/def/
ch/
ch/ZEF/
ch/abc/
ch/def/
ch/temp/
df/
df/ZEF/
df/abc/
df/def/
dg/
dg/ZEF/
dg/abc/
dg/def/
dg/temp/
dg/temp/temp/
dh/
dh/ZEF/
dh/abc/
dh/def/
dh/temp/
# ただしc** は、globstar offのときと同じ動作する
$ ls -1d c**
cf
cg
ch
?

任意の1文字にマッチします。

# cで始まる2文字のファイルにマッチする
$ ls -1d c?
cf
cg
ch
# hで終わる2文字のファイルにマッチする
$ ls -1d ?h
ch
dh
eh
# hで終わるディレクトリ以下のtempにマッチする
$ ls -1d ?h/temp
ch/temp
dh/temp
# アルファベット数字以外の記号にもマッチする
## 記号1文字のファイルを作成する
$ touch + @
$ ls
+  @  abc  cf  cg  ch  def  df  dg  dh  ghi
# ?は、記号にもマッチする
$ ls ?
+  @
[...]

[]で囲まれた文字の、任意の1文字にマッチします。また文字間を-を結ぶことで、前後の文字の範囲を指します。範囲の順序はASCII文字列順にマッチします。つまり、[A-Z]は有効ですが、[z-a]は無効です。また、[A-Za-z0-9%+-]のように組み合わせ可能です。

# アルファベット大文字と数字のファイルを用意する
$ touch ABC XYZ 012 345 678
$ echo *
+ 012 345 678 @ ABC XYZ abc cf cg ch def df dg dh ghi
# A と g で始まるファイル名
$ echo [Ag]*
ABC ghi
# アルファベット小文字で始まるファイル名
$ echo [a-z]*
abc cf cg ch def df dg dh ghi
# アルファベット大文字と数字で始まるファイル名
$ echo [A-Z0-9]*
012 345 678 ABC XYZ
# 数字とa で始まるファイル名
$ echo [0-9a]*
012 345 678 abc
# [+-@]だと、ASCII文字順の範囲なので数字も含まれる
$ echo [+-@]*
+ 012 345 678 @
# [z-a]は不正な表現としてそのまま表示される
$ [z-a]*

[]の先頭が^もしくは!の場合、指定した文字列にマッチしない文字列を指します。

# a 以外で始まるファイル名
$ echo [^a]*
+ 012 345 678 @ ABC XYZ cf cg ch def df dg dh ghi
$ echo [!a-c]*
+ 012 345 678 @ ABC XYZ def df dg dh ghi
# aからcと0以外で始まるファイル名
$ echo [^a-c0]*
+ 345 678 @ ABC XYZ def df dg dh ghi
$ echo [!a-c0]*
+ 345 678 @ ABC XYZ def df dg dh ghi

[]の間にPOSIX文字クラスclassを、[[:class:]]のように指定できます。以下はbashで使用できる文字クラスです。

文字クラス 説明
alnum アルファベットと十進数の数字([0-9a-zA-Z])
alpha アルファベット([a-zA-Z])
ascii すべてのASCII文字([0X00-0X7F])
blank 空白またはTAB([ \t])
cntl 制御文字([0X00~0X1FX7F])
digit 十進数数字([0-9])
graph 表示できる文字([[:alnum:][:punct:]])
lower アルファベット小文字([a-z])
print プリント可能文字列([[:graph:]0X20])
punct 句読文字(``[!"#$%&'()*+,-./:;<=>?@[¥]^_`{
space 空白文字([ \t\n0XB\f\r])
upper アルファベット大文字([A-Z])
word アルファベットと10進数の数字と_ ([[:alnum:]_])
xdigit 16進数数字([0-9a-fA-F])
# アルファベットと十進数の数字
$ ls -d [[:alnum:]]*
012  345  678  ABC  XYZ  abc  cf  cg  ch  def  df  dg  dh  ghi
# アルファベット
$ ls -d [[:alpha:]]
ABC  XYZ  abc  cf  cg  ch  def  df  dg  dh  ghi
# すべてのASCII文字(1文字)
$ ls -d [[:ascii:]]
+  @
# 空白文字以外
$ ls -d [^[:blank:]]*
+  012  345  678  @  ABC  XYZ  abc  cf  cg  ch  def  df  dg  dh  ghi
# 数字
$ ls -d [[:digit:]]*
012  345  678
# 制御文字以外
$ ls -d [^[:cntl:]]*
+  012  345  678  @  ABC  XYZ  abc  cf  cg  ch  def  df  dg  dh  ghi
# 表示できる文字
$ ls -d [[:graph:]]*
+  012  345  678  @  ABC  XYZ  abc  cf  cg  ch  def  df  dg  dh  ghi
# アルファベット小文字
$ ls -d [[:lower:]]*
abc  cf  cg  ch  def  df  dg  dh  ghi
# プリント可能文字
$ ls -d [[:print:]]*
+  012  345  678  @  ABC  XYZ  abc  cf  cg  ch  def  df  dg  dh  ghi
# 句読文字
$ ls -d [[:punct:]]*
+  @
# アルファベット大文字
$ ls -d [[:upper:]]*
ABC  XYZ
# アルファベットと10進数の数字と_
$ ls -d [[:word:]]*
012  345  678  ABC  XYZ  abc  cf  cg  ch  def  df  dg  dh  ghi
# 16進数表記で使用する文字
$ ls -d [[:xdigit:]]*
012  345  678  ABC  abc  cf  cg  ch  def  df  dg  dh
終わりに

今回は、単語分割とパス展開について説明しました。パス展開などはbashを使用する上でよく使用します。次回は環境変数、終了コード、シグナルについて説明します。次回をお楽しみに。

 


 

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  Microsoft Azure  Docker  Kubernetes