回答:
を使用-b
してバイトオフセットを取得できます。これは、単純なテキストの位置と同じです(ただし、UTF-8などではありません)。
$ echo "RAMSITALSKHMAN|1223333" | grep -aob '|'
14:|
上記では、-a
スイッチを使用して、入力をテキストとして使用するようにgrepに指示しています。バイナリファイルを操作するときに必要であり-o
、一致する文字のみを出力するスイッチ。
位置だけが必要な場合は、grepを使用して位置のみを抽出できます。
$ echo "RAMSITALSKHMAN|1223333" | grep -aob '|' | grep -oE '[0-9]+'
14
奇妙な出力が表示される場合は、grepで色が有効になっているかどうかを確認してください。色を無効にするには--colors=never
、grepに渡すか、grepコマンドの前に\
(エイリアスを無効にします)を付けます。例:
$ echo "RAMSITALSKHMAN|1223333" | grep -aob '|' --color=never | \grep -oE '^[0-9]+'
14
複数の一致を返す文字列の場合head -n1
、最初の一致を取得するためにパイプスルーします。
上記の両方を使用していることに注意してください。後者は、実行可能ファイル(スクリプトなど)を介してgrepが「エイリアス」されている場合、エイリアスを使用する場合にのみ機能しません。
2
;)を検索してください
^
:)
0:|
として取得します。0は、|
見つかった行の先頭のバイト位置だからです。
grep (GNU grep) 2.27
。OS Xを使用していますか?
試してください:
printf '%s\n' 'RAMSITALSKHMAN|1223333.' | grep -o . | grep -n '|'
出力:
15:|
これにより、index based-1の位置が得られます。
printf '%s\n' '|' | grep -o . | grep -n '|'
期待どおり1
ではなく0
、印刷します。
bashシェルを使用している場合は、grepやawkなどの外部プロセスを生成する必要なく、純粋に組み込みの操作を使用できます。
$ str="RAMSITALSKHMAN|1223333"
$ tmp="${str%%|*}"
$ if [ "$tmp" != "$str" ]; then
> echo ${#tmp}
> fi
14
$
これは、パラメータ展開を使用して、|
任意の文字列によるfollowのすべての出現を削除し、それを一時変数に保存します。次に、一時変数の長さを測定してのインデックスを取得するだけです|
。
が元の文字列に存在if
するかどうかを確認していることに注意してください|
。そうでない場合、一時変数は元の変数と同じになります。
また、これは0ベースのインデックスを提供し、そのインデックス|
は通常、bash文字列にインデックスを付けるときに役立ちます。ただし、1から始まるインデックスが必要な場合は、次のようにすることができます。
$ echo $((${#tmp}+1))
15
$
awkのindex
関数を使用して、一致が発生した位置を文字で返すことができます。
echo "RAMSITALSKHMAN|1223333"|awk 'END{print index($0,"|")}'
15
Perlのindex
関数を使用してもかまわない場合、これは文字の0回または1回以上の出現を報告します。
echo "|abc|xyz|123456|zzz|" | \
perl -nle '$pos=-1;while (($off=index($_,"|",$pos))>=0) {print $off;$pos=$off+1}'
読みやすくするためにのみ、パイプラインは2行に分割されています。
ターゲット文字が見つかる限りindex
、ゼロ(0)を基準とする正の値を返します。したがって、文字列「abc | xyz | 123456 | zzz |」解析すると、位置0、4、8、15、19が返されます。
RAMSITALSKHMAN|1|223333
「expr match」または「expr index」を使用してそれを行うこともできます
expr match $ string $ substring $ substringはREです。
echo `expr match "RAMSITALSKHMAN|1223333" '[A-Z]*.|'`
そして、上記は一致した部分文字列の長さを返すため、位置を示します。
しかし、インデックスを検索するためにより具体的には:
mystring="RAMSITALSKHMAN|122333"
echo `expr index "$mystring" '|'`
awk
ファイルのすべての行でこの情報をレポートするためにソリューションを簡単に変更できるため(END
JRFergusonの回答から、本当に必要ではなかったを削除するだけで、Avinash Rajはすでにそれを実行しています) ; 一方、expr
ソリューションでそれを行うには、明示的なループを追加する必要があります(そして、Gnoucの答えはそれを行うために簡単に適応できません、私が見ることができます)、および(2)awk
ソリューションはすべての各行での一致は、expr
解決策よりもいくぶん簡単です(実際、Avinash Raj'sでも既に行われています)。
echo `...`
ここで使うのですか?
いくつかの選択肢は次のとおりです。
Gnoucの答えに似ていますが、シェルがあります:
echo 'RAMSITALSKHMAN|1223333' |
tr -c \| \\n |
sh
sh: line 15: syntax error near unexpected token `|
sh: line 15: `|'
sed
し、dc
場合によっては複数行にまたがります:
echo 'RAMSITALSKHMAN|1223333' |
sed 's/[^|]/1+/g;s/|/p/;1i0 1+' |dc
15
と$IFS
...
IFS=\|; set -f; set -- ${0+RAMSITALSKHMAN|1223333}; echo $((${#1}+1))
それはまた、どのようにあなたを教えてくれる多くのようにあります...
echo $(($#-1))