私はあなただけでこれを行うことができると信じてgrep
、sort
とtail
にも。文字列の例をいくつか示します。
$ echo <str> | grep -oP "\d+" | sort -n | tail -1
<str>
問題の文字列はどこにありますか。
例
$ set -o posix; set | grep "str[0-9]"
str0=212334123434test233
str1=212334123434test233abc44
str2=233test212334123434
str3=a212334123434test233abc44
str4=a91234b212334123434abc
これらのgrep ...
コマンドを順番に実行すると、
$ echo $str0 | grep -oP "\d+" | sort -n | tail -1
212334123434
$ echo $str1 | grep -oP "\d+" | sort -n | tail -1
212334123434
$ echo $str2 | grep -oP "\d+" | sort -n | tail -1
212334123434
$ echo $str3 | grep -oP "\d+" | sort -n | tail -1
212334123434
$ echo $str4 | grep -oP "\d+" | sort -n | tail -1
212334123434
このアプローチは、数字のシーケンスであるすべての部分文字列を選択することによって機能します。次に、この出力を数値で並べ替えsort -n
、を使用して、リストの最後の値を取得しtail -1
ます。これは最も長い部分文字列になります。
次tail -1
の例のいずれかを脱いで再実行することで、それがどのように機能するかを確認できます。
$ echo $str4 | grep -oP "\d+" | sort -n
91234
212334123434
ゼロで始まる文字列
上記のアプローチは、1つを除いて、考えられるすべての状況で機能します。@terdonは、チャットで上記のアプローチを無効にするこのシナリオについて言及しました。
したがって、これに対処するには、戦術を少し変更する必要があります。上記のアプローチのカーネルは引き続き活用できますが、結果に文字数も挿入する必要があります。これにより、文字列の文字数とその値で結果を並べ替えることができます。
$ for i in $(echo $str0 | grep -oP "\d+");do a=$(echo "$i" | wc -c); \
echo "$a $i"; done | sort -n | tail -1 | cut -d" " -f2
結果:
$ echo $str0
0000000000001a2test
$ for i in $(echo $str0 | grep -oP "\d+");do a=$(echo "$i" | wc -c); \
echo "$a $i"; done | sort -n | tail -1 | cut -d" " -f2
0000000000001
を使用して変数の長さを決定するBashの機能を利用して、これを少し凝縮することができます${#var}
。
$ for i in $(echo $str0 | grep -oP "\d+");do echo "${#i} $i"; done | \
sort -n | tail -1 | cut -d" " -f2
0000000000001
`grep -Pを使用する
私はgrep -P ...
、Perlの開発者であるため、すべての桁を次のように言うクラス構文のよう\d+
に、[[:digit:]]\+
またはの代わりに、上記を使用することにしました[0-9]\+
。しかし、この特定の問題では、それは実際には必要ありません。grep
私が使用したのと同じくらい簡単に交換できます:
$ .... grep -o "[0-9]\+" ....
例えば:
$ for i in $(echo $str0 | grep -o "[0-9]\+");do echo "${#i} $i"; done | \
sort -n | tail -1 | cut -d" " -f2
0000000000001