web-dev-qa-db-ja.com

文字列の一部をbashの変数に抽出する

ここでnoob、再投稿した場合は申し訳ありません。私はファイルから文字列を抽出し、次のような行で終わります:

abcdefg:12345:67890:abcde:12345:abcde

TestStringという名前の変数で、コロンの間の値の長さが一定でないとしましょう。しかし、2番目と3番目のコロンの間の文字列で問題ないので、数値を変数に保存します。したがって、この場合、新しい変数が作成されるので、抽出された名前を67890にしましょう。私はsedを使用する必要があると思いますが、sedを使用したことがなく、頭を動かそうとはしていません...誰か助けてもらえますか?乾杯

補足として、findを使用して、最初の文字列(この場合はabcdefgの部分)を検索することにより、文字列から行全体を抽出しています。

15
Steven Cragg

これがもう1つの純粋なbashの方法です。入力が適度に一貫していて、どのセクションを選択するかについてあまり柔軟性を必要としない場合は、うまく機能します。

extractedNum="${testString#*:}"     # Remove through first :
extractedNum="${extractedNum#*:}"   # Remove through second :
extractedNum="${extractedNum%%:*}"  # Remove from next : to end of string

また、たとえば、whileループで、ファイルを読み取りながらフィルタリングすることもできます。

while IFS=' ' read -r col line ; do
    # col has the column you wanted, line has the whole line
    # # #
done < <(sed -e 's/\([^:]*:\)\{2\}\([^:]*\).*/\2 &/' "yourfile")

Sedコマンドは2番目の列を取り出し、その値を行全体からスペースで区切ります。行全体が不要な場合は、置換からスペース+&を削除して、行変数を読み取りから削除します。\{2 \}ビットの数値を変更することで、任意の列を選択できます。 (そこで変数を使用する場合は、コマンドを二重引用符で囲みます。)

10
William

配列を使用した純粋なBash:

testString="abcdefg:12345:67890:abcde:12345:abcde"
IFS=':'
array=( $testString )
echo "value = ${array[2]}"

出力:

value = 67890
16
Fritz G. Mehner

この種のものにはcutを使用できます。どうぞ:

VAR=$(echo abcdefg:12345:67890:abcde:12345:abcde |cut -d":" -f3); echo $VAR

面白くするために、これは私がsedでこれを行う(しない)方法ですが、もっと簡単な方法があると確信しています。それは将来の読者にとって私自身の問題になると思います;)

echo abcdefg:12345:67890:abcde:12345:abcde |sed -e "s/[^:]*:[^:]*:\([^:]*\):.*/\1/"
5
Miquel

これはうまくいくはずです:重要な部分はawk -F: '$0=$3'

NewVar=$(getTheLineSomehow...|awk -F: '$0=$3')

例:

kent$  newVar=$(echo "abcdefg:12345:67890:abcde:12345:abcde"|awk -F: '$0=$3')

kent$  echo $newVar 
67890

テキストがvar testStringに保存されている場合、次のことができます。

kent$  echo $testString                                                                                                                                                     
abcdefg:12345:67890:abcde:12345:abcde
kent$  newVar=$(awk -F: '$0=$3' <<<"$testString")
kent$  echo $newVar                                                                                                                                                         
67890
2
Kent