Bashスクリプトでは、
1つ以上のスペースで区切られたいくつかの単語を含む文字列があります。つまり:
Name Age Sex ID Address
Wordのいずれかを検索する場合、たとえばWord "Age"のインデックスを検索する場合、どうすればよいですか?
必要なWordのインデックス番号を直接返すコマンドはありますか?
ありがとう。
Bashは文字列内で Word splitting を単独で実行します–実際、たいていの場合、それを回避することが問題であり、引用が非常に重要な理由です。これを活用するのは簡単です。引用符なしで文字列を配列に入れるだけです。bashはWord分割を使用して個々の要素を分離します。文字列が変数$str
に格納されていると仮定すると、
ar=($str) # no quotes!
5つの要素の配列を返します。配列インデックスは、Wordインデックス(ほとんどのスクリプト言語やプログラミング言語のように0からカウントアップ)です。つまり、「年齢」は次を使用してアクセスされます。
${ar[1]} # 0 => Name, 1 => Age, 2 => Sex, 3 => ID, 4 => Address
または、コンテンツによって要素のインデックスを検索する必要がある場合は、配列をループします。
function el_index {
cnt=0; for el in "${ar[@]}"; do
[[ $el == "$1" ]] && echo $cnt && break
((++cnt))
done
}
el_index "Age" # => 1
$ export FOO="Name Age Sex ID Address"
* AgeをAgeに置き換えます。これにより、「Age」の前のものがすべて削除されます。
$ echo ${FOO/*Age/Age}
Age Sex ID Address
「年齢」より前に何でも入手
$ echo ${FOO/Age*/}
Name
その文字列の長さ( "Age"のインデックス)を取得します。
$ BEGIN=${FOO/Age*/}
$ echo ${#BEGIN}
7
シェルで次のjavascript onelinerを試してください(javascript Shellを使用)。
$ js <<< "x = 'Name Age Sex ID Address'; print(x.indexOf('Age'));"
7
または、ヒアドキュメントを使用して:
js <<EOF
x = 'Name Age Sex ID Address';
print(x.indexOf('Age'));
EOF
Coreutilsが利用可能な場合は、次の方法で実行できます。
エコー$ {str/Age //} |カット-d/-f1 | wc -w
MariusMatutiaeのリクエストごとに、この3つのステップの操作がどのように機能するかについての説明を追加します。
echo $ {str/Age //}1。一意の文字を検索する文字列を置換します(私の場合は/)
カット-d/-f12。一意の文字の後にある文字列全体を切り取ります
wc -w3。残っている単語を数えて印刷すると、インデックス番号が得られます
参考のために確認してください:
http://www.tldp.org/LDP/abs/html/parameter-substitution.html (「変数の拡張/部分文字列の置換」に移動します)
http://www.gnu.org/software/coreutils/manual/coreutils.html (「cutコマンド」と「wc呼び出し」に移動します
注:ここで、インデックスによって、文字列内の文字ではなく、どのWordが(0から始まる)かを知りたいと仮定すると、みことばが始まる。他の答えは後者に対処します。
私が知っていることではありませんが、あなたはそれを作ることができます。 2つのトリック:
コード:
#!/bin/bash
find_index() {
local str=$1
local search=$2
let local n=0
local retval=1 # here, 1 is failure, 0 success
for col in $str; do # $str unquoted -> whitespace tokenization!
if [ $col = $search ]; then
echo $n
retval=0
break
else
((n++))
fi
done
return $retval
}
test="Name Age Sex ID Address"
idx=`find_index "$test" Age`
if [ $? -ne 0 ]; then
echo "Not found!"
else
echo "Found: $idx"
fi
厳密にbashを使用する必要はないが、bashを使用するシステムで一般的に見られる他のプログラムを使用できる場合は、次のようなものを使用できます。
echo "Name Age Sex ID Addr" | python -c 'print(raw_input().index("Age"))+1'
Pythonは文字列のインデックス作成をゼロから開始するため、コマンドの最後に+1を追加しました。
私はうまく機能する解決策を見つけました。
$ string = 'now is the time'
$ buf = the $ {string#* the}
$エコー$ buf
出力:時間
$ index = $(($ {#string}-$ {#buf} + 1))
$エコー$インデックス
出力:8->最初の単語「the」のインデックス
これは、Javaの関数indexOf()と同様に機能し、入力文字列の最初の出現を返します。
この解決策はここで見つかりました http://www.linuxquestions.org/questions/linux-newbie-8/bash-string-manipulation-help-670627/ (最後の投稿)。この男は私の日を救った。彼の功績です。
最初のindexofから部分文字列を作成する場合の高速化。
$ a = "some long string"
$ b = "ri"
$エコー$ {a/* $ b/$ b}
リング
$エコー$ {a/$ b */$ b}
いくつかの長い線条
https://stackoverflow.com/questions/10349102/Shell-script-substring-from-first-indexof-substring
Bashのネイティブ正規表現を使用できます
# a function to print the index of a field and its name
printIx() {
for ((l=0,i=1;i<$1;i++)) ;do
((l+=${#BASH_REMATCH[i]}))
done
printf '%3s %s\n' $l "$2"
}
# Using a zero based index
# "0----+----1----+----2----+----3----+----4"
str=" Name Age Sex ID Address "
if [[ $str =~ ^(\ *)(Name)(\ +)(Age)(\ +)(Sex)(\ +()ID)(\ +)(Address)\ *$ ]] ;then
F=(Name Age Sex ID Address)
f=( 2 4 6 8 10) # regex back-references
for ((g=0;g<${#f[@]};g++)) ;do
printIx ${f[g]} "${F[g]}"
done
fi
出力
2 Name
9 Age
13 Sex
20 ID
29 Address