シェルスクリプトで文字列の特定の位置にある文字を取得する方法は?


回答:


35

「パラメータ拡張」とbashで$ {parameter:offset:length}

$ var=abcdef
$ echo ${var:0:1}
a
$ echo ${var:3:1}
d

編集:パラメータ展開なし(あまりエレガントではないが、それが最初に私に来たものです)

$ charpos() { pos=$1;shift; echo "$@"|sed 's/^.\{'$pos'\}\(.\).*$/\1/';}
$ charpos 8 what ever here
r

1
gnu.org/software/bash/manual/…に詳細があります
-jsbillings


また、そのような「末端から」オフセットを設定することができますecho ${var: -2:1}
ヴァシリス

この構文はksh93から来ており、およびによってもサポートされzshていmkshます。
ステファンシャゼラス

6

パラメーター展開の代替手段は expr substr

substr STRING POS LENGTH
    substring of STRING, POS counted from 1

例えば:

$ expr substr hello 2 1
e

クール、exprをより徹底的にチェックする必要があります。
forcefsck

1
これはGNU coreutilsのexprで動作するように見えsubstrますが、FreeBSD、NetBSDまたはOS Xのexprには含まれていません。これは移植性のあるソリューションではありません。
ゴッティ

@ghoti、substr元々はGNU拡張ではないことに注意してください。の最初の実装はexpr、70年代後半にPWB Unixから来て、持っていましたsubstr(ではありません:)。
ステファンシャゼラス

@StéphaneChazelas、歴史的視点を追加してくれてありがとう。:) PWBの使用はOPには関係ないと確信していますが、何十年も機能や変更を追跡することは常に楽しいです。GNUは多くの人々のデフォルトになる傾向がありますが、一般的に、明らかにPOSIXではなく、主要なユニシスに欠けていることが知られているオプションの使用は避けたいと思います。
ゴッティ

5

cut -c

変数に改行が含まれていない場合は、次を実行できます。

myvar='abc'
printf '%s\n' "$myvar" | cut -c2

出力:

b

awk substr 変数に改行がある場合でも機能する別のPOSIXの代替手段です。

myvar="$(printf 'a\nb\n')" # note that the last newline is stripped by
                           # the command substitution
awk -- 'BEGIN {print substr (ARGV[1], 3, 1)}' "$myvar"

出力:

b

printf '%s\n'エスケープ文字に関する問題を回避することです:https : //stackoverflow.com/a/40423558/895245例:

myvar='\n'
printf '%s\n' "$myvar" | cut -c1

\期待どおりに出力します。

参照:https : //stackoverflow.com/questions/1405611/extracting-first-two-characters-of-a-string-shell-scripting

Ubuntu 19.04でテスト済み。


printf '%s' "$myvar" | cut -c2改行文字で終了しprintfない限り、の出力はテキストではないため、POSIXではありません$myvar。それ以外の場合は、入力の各行cutカットするときに変数に改行文字が含まれないと想定します。
ステファンシャゼル

awk一つはとのより効率的で信頼性の高いだろうawk -- 'BEGIN {print substr (ARGV[1], 2, 1)}' "$myvar"
ステファンChazelas

なお、GNUの現在のバージョンとcut(のmawkやbusyboxののawkのために同じ)マルチバイト文字のための仕事をしない、
ステファンChazelas

@StéphaneChazelasの点に感謝します。私はあなたが最初のものの意味を理解していませんでした:printf 'abc '| cut -c2いいえ\n(これは私は知りません)のために間違っているのですか、myvarに改行があるとコマンドが失敗するのですか(これは同意します)?
Ciro Santilli新疆改造中心法轮功六四事件

1
cut入力がテキストでない場合の動作は指定cutされていません(ただし、行または任意の長さを処理するには実装が必要です)。の出力は改行文字で終わらないため、テキストprintf abcはありません。実際には、実装に応じて、それをにパイプすると、のいずれかが得られるか、まったく得られません。あなたは、必要があると思います(のは、出力に必要なことをPOSIXによって指定された動作を取得するために)cut -c2bb<newline>printf 'abc\n' | cut -c2b<newline>
ステファンChazelas


0

cutコマンドを使用できます。3番目の位置を取得するには:

echo "SAMPLETEXT" | cut -c3

このリンクを確認してくださいhttp://www.folkstalk.com/2012/02/cut-command-in-unix-linux-examples.html

高度な場合)ただし、特に入力にスペースが含まれる場合は、IFSを変更することも良いことです。その場合のみ、以下のものを使用してください

saveifs=$IFS
IFS=$(echo -en "\n\b")
echo "SAMPLETEXT" | cut -c3
IFS=$saveifs

IFSあなたが投稿したコードでは、どのように作用するかわかりません。
クサラナナンダ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.