web-dev-qa-db-ja.com

文字列の一部を知りながら文字列を検索して文字列を返す

たとえば、文字列があります

"Icecream123 AirplaneBCD CompanyTL1 ComputerYU1"

私の文字列には必ず部分文字列IceCreamが含まれていることはわかっていますが、その後に何があるかわかりません。

それは私の例のように123かもしれませんし、何か違うかもしれません。

次のコマンドを使用して、grepを使用して文字列に「Icecream」サブストリングが存在するかどうかを検出できますが

echo $string | grep -oF 'Icecream';

どちらが印刷されます

Icecream

部分文字列全体を出力するコマンドを使用したいのですが、私の例では

Icecream123

もちろん、アイスクリームに続くものはランダムで事前にわかっていないので、私はただ行うことができません

$SUBSTRING=$(echo $string | grep -oF 'Icecream')
$SUBSTRINGTRAIL=123
echo $SUBSTRING$SUBSTRINGTRAIL
8
Sonamor

grepがPerl互換の正規表現をサポートしている場合、次のWord境界まで貪欲に一致しない可能性があります。

echo "$string" | grep -oP 'Icecream.*?\b'

それ以外の場合は、非ブランク文字の最も長いシーケンスに一致します。

echo "$string" | grep -o 'Icecream[^[:blank:]]*'

または、シェルにすべてを保持し、スペースで始まる最も長い末尾の文字シーケンスを削除します。

echo "${string%% *}"
15
steeldriver

-oを知っているgrepを使用する:

$ printf '%s\n' "$string" | grep -o '\<Icecream[^[:blank:]]*'
Icecream123

パターン\<Icecream[^[:blank:]]*は、文字列IcecreamIの前に非Word文字または行の先頭が続く)と一致し、その後に0個以上の非空白文字(スペースやタブではありません)。


awkの使用:

$ printf '%s\n' "$string" | awk -v RS=' ' '/^Icecream/'       
Icecream123

awkプログラムは、文字列をスペースで区切られたレコードに分割し、それぞれをテストします。文字列Icecreamで始まるものを出力します。

mawkまたはGNU awkを使用して、

printf '%s\n' "$string" | awk -v RS='[[:blank:]]' '/^Icecream/'

複数の文字が含まれている場合、正規表現としてRSを解釈するためです。


sedでは、grepと同様の方法で:

$ printf '%s\n' "$string" | sed 's/.*\(\<Icecream[^[:blank:]]*\).*/\1/'
Icecream123

/bin/shの使用:

set -- Icecream123 AirplaneBCD CompanyTL1 ComputerYU1
for string; do
    case $string in
        Icecream*)
            printf '%s\n' "$string"
            break
    esac
done

Perl(trの少しの助けを借りて):

$ printf '%s\n' "$string" | tr ' ' '\n' | Perl -ne '/Icecream\S*/ && print'
Icecream123

あるいは単に

$ printf '%s\n' "$string" | Perl -ne '/(Icecream\S*)/ && print $1, "\n"'
Icecream123
7
Kusalananda

Bashにタグを付けてから:

[[ $string =~ (Icecream[^ ]*) ]] && result=${BASH_REMATCH[1]}

より一般的には、$searchの検索用語の場合:

[[ $string =~ ($search[^ ]*) ]] && result=${BASH_REMATCH[1]}

...またはパラメータ拡張あり:

# remove any leading text up to -and through- the search text:
x=${string##*$search}

# remove any trailing space onwards
result=$search${x%% *}
7
Jeff Schaller

たとえば、GNU grep

$ echo "Icecream123 AirplaneBCD CompanyTL1 ComputerYU1" | grep -oP '\bIcecream.*?(\s|$)' --color

PCREを使用します。

2

特にgrepのバージョンがPerl正規表現をサポートしていないと言っているので、おそらく少し単純になります。

$ echo $string | tr ' ' '\n' | grep 'Icecream' Icecream123

trは、すべてのスペースを改行で置き換えることにより、文字列を行に分割します。その後、grepを簡単に使用できます。

また、次のように記述して、探しているWordに続くものだけを取得することもできます。

$ echo $string | tr ' ' '\n' | sed -n 's/Icecream//p' 123

1
Law29