私はこのような文字列を持っています:
/var/cpanel/users/joebloggs:DNS9=domain.com
この文字列からユーザー名(joebloggs
)を抽出して変数に格納する必要があります。
joebloggs
とdomain.com
を除いて、文字列のフォーマットは常に同じですので、cut
を使用して文字列を2回分割できると思いますか
最初の分割は:
で分割し、最初の部分を変数に格納して2番目の分割関数に渡します。
2番目の分割は/
で分割し、最後のWord(joebloggs
)を変数に格納します。
私は配列と分割を使ってphpでこれを行う方法を知っていますが、私はbashで少し迷っています。
追加のプロセスなしでパラメータ展開を使用してbashでこの文字列からjoebloggs
を抽出するには...
MYVAR="/var/cpanel/users/joebloggs:DNS9=domain.com"
NAME=${MYVAR%:*} # retain the part before the colon
NAME=${NAME##*/} # retain the part after the last slash
echo $NAME
パスの特定の深さにあるjoebloggs
には依存しません。
要約
参考のために、いくつかのパラメータ拡張モードの概要...
${MYVAR#pattern} # delete shortest match of pattern from the beginning
${MYVAR##pattern} # delete longest match of pattern from the beginning
${MYVAR%pattern} # delete shortest match of pattern from the end
${MYVAR%%pattern} # delete longest match of pattern from the end
そのため、#
は最初からの一致を意味し(コメント行を考える)、%
は最後からの一致を意味します。 1つのインスタンスは最短を意味し、2つのインスタンスは最長を意味します。
数字を使って位置に基づいて部分文字列を取得できます。
${MYVAR:3} # Remove the first three chars (leaving 4..end)
${MYVAR::3} # Return the first three characters
${MYVAR:3:5} # The next five characters after removing the first 3 (chars 4-9)
以下を使って特定の文字列やパターンを置き換えることもできます。
${MYVAR/search/replace}
pattern
はファイル名のマッチングと同じ形式であるため、*
(任意の文字)が一般的であり、多くの場合は/
または.
のような特定の記号が続きます。
例:
のような変数を考える
MYVAR="users/joebloggs/domain.com"
ファイル名を残すパスを削除します(スラッシュまでのすべての文字)。
echo ${MYVAR##*/}
domain.com
パスを残してファイル名を削除します(最後の/
の後の最短一致を削除します)。
echo ${MYVAR%/*}
users/joebloggs
ファイル拡張子だけを取得します(最後の期間の前にすべて削除します)。
echo ${MYVAR##*.}
com
注:2つの操作を行うには、それらを組み合わせることはできませんが、中間変数に代入する必要があります。パスや拡張子を付けずにファイル名を取得するには:
NAME=${MYVAR##*/} # remove part before last slash
echo ${NAME%.*} # from the new var remove the part after the last period
domain
このように関数を定義します。
getUserName() {
echo $1 | cut -d : -f 1 | xargs basename
}
そして、文字列をパラメータとして渡します。
userName=$(getUserName "/var/cpanel/users/joebloggs:DNS9=domain.com")
echo $userName
Sedについてはどうですか?それは単一のコマンドで動作します。
sed 's#.*/\([^:]*\).*#\1#' <<<$string
#
が含まれているため、/
は/
の代わりに正規表現の区切り文字に使用されています。.*/
は、最後のバックスラッシュまで文字列を取り込みます。\( .. \)
はキャプチャグループをマークします。これは\([^:]*\)
です。[^:]
はコロン以外の任意の文字を表し、*
はゼロ以上を意味します。.*
は行の残りを意味します。\1
は最初の(そして唯一の)キャプチャグループで見つかったものを置き換えることを意味します。これが名前です。これが、正規表現と文字列を一致させる内訳です。
/var/cpanel/users/ joebloggs :DNS9=domain.com joebloggs
sed 's#.*/ \([^:]*\) .* #\1 #'
シングルsedを使用する
echo "/var/cpanel/users/joebloggs:DNS9=domain.com" | sed 's/.*\/\(.*\):.*/\1/'
単一のAwkを使う:
... | awk -F '[/:]' '{print $5}'
つまり、フィールド区切り文字として/
または:
を使用すると、ユーザー名は常にフィールド5に入ります。
変数に格納するには
username=$(... | awk -F '[/:]' '{print $5}')
ユーザー名がフィールド5である必要がない、sed
を使用したより柔軟な実装。
... | sed -e s/:.*// -e s?.*/??
つまり、:
以降のすべてを削除し、最後の/
までのすべてを削除します。 sed
はおそらくawk
よりも速いので、この方法は間違いなく優れています。