たとえば、次の場合:
USCAGoleta9311734.5021-120.1287855805
抽出したいだけです:
US
たとえば、次の場合:
USCAGoleta9311734.5021-120.1287855805
抽出したいだけです:
US
回答:
おそらく、bashシェルを使用している(そしてコメントに基づいて使用しているように見える)場合、最も効率的な方法は、パラメーター拡張のサブストリングバリアントを使用することです。
pax> long="USCAGol.blah.blah.blah"
pax> short="${long:0:2}" ; echo "${short}"
US
これはshortの最初の2文字に設定されますlong。longが2文字より短い場合は、shortそれと同じになります。
プロセスを作成するオーバーヘッドがないため、このインシェルメソッドは、多くの場合(レポートごとに50,000回など)行う場合に適しています。外部プログラムを使用するすべてのソリューションは、そのオーバーヘッドの影響を受けます。
最小の長さも確保したい場合は、事前に次のようなものを埋め込むことができます。
pax> long="A"
pax> tmpstr="${long}.."
pax> short="${tmpstr:0:2}" ; echo "${short}"
A.
これにより、長さが2文字未満の場合は、右側にピリオドが埋め込まれます(または、何かを作成するときに使用される文字を変更するだけでtmpstr)。これが必要かどうかは明らかではありませんが、完全を期すために入れておきます。
そうは言っても、外部プログラムを使用してこれを行う方法はいくつもあります(bash使用できない場合など)。そのいくつかは次のとおりです。
short=$(echo "${long}" | cut -c1-2)
short=$(echo "${long}" | head -c2)
short=$(echo "${long}" | awk '{print substr ($0, 0, 2)}'
short=$(echo "${long}" | sed 's/^\(..\).*/\1/')
最初の2つ(cutおよびhead)は、単一行の文字列と同じです。基本的には、どちらも最初の2文字を返すだけです。彼らはcutあなたに各行の最初の2文字を与えるという点で異なり、headの最初の2文字を提供し、入力全体の最初の2文字をます。
3番目は、awkサブストリング関数を使用して最初の2文字を抽出し、4番目はsedキャプチャグループ(()およびを使用\1)を使用して最初の2文字をキャプチャし、行全体をそれらに置き換えます。どちらも似ていますcut-入力の各行の最初の2文字を配信します。
入力が単一の行であることが確実である場合、それらはどれも重要ではありません。それらはすべて同じ効果をもたらします。
printf '%s'代わりのをecho:奇妙な文字が文字列である場合にはstackoverflow.com/a/40423558/895245 POSIXの場合は取り付か:head -cPOSIXではない、cut -cとawk substr、あるsed \1かわかりません。
最も簡単な方法は
${string:position:length}
これ$lengthが$stringat から部分文字列を抽出する場所$positionます。
これはbashの組み込みなので、awkやsedは必要ありません。
あなたは、いくつかの良い答えを得ていると私は自分自身組み込みバッシュで行くと思いますが、あなたはについて尋ね以来sedとawkと(ほとんどそれらに基づいて)誰も他に提供するソリューションは、私はあなたにこれらを提供します:
echo "USCAGoleta9311734.5021-120.1287855805" | awk '{print substr($0,0,2)}'
そして
echo "USCAGoleta9311734.5021-120.1287855805" | sed 's/\(^..\).*/\1/'
awk一つはかなり明白であるべきだが、ここでの説明ですsed1:
substr($0,1,2)。
にいる場合はbash、次のように言うことができます。
bash-3.2$ var=abcd
bash-3.2$ echo ${var:0:2}
ab
これで十分かもしれません…
ただgrep:
echo 'abcdef' | grep -Po "^.." # ab
-Pオプションを削除して短くすることができます。すべての正規表現はそのパターンを理解します。
使用できますprintf:
$ original='USCAGoleta9311734.5021-120.1287855805'
$ printf '%-.2s' "$original"
US
かなり遅いですが、ここにあります
sed 's/.//3g'
または
awk NF=1 FPAT=..
または
perl -pe '$_=unpack a2'
シェルスクリプトを使用し、POSIX以外の拡張機能(いわゆるbashismなど)に依存しない場合は、grep、sed、cut、awkなどの外部ツールをフォークする必要のない手法を使用できます。スクリプトの効率を下げます。おそらく、効率とposixの移植性はユースケースでは重要ではありません。しかし、それが(または良い習慣として)場合は、次のパラメーター拡張オプションメソッドを使用して、シェル変数の最初の2文字を抽出できます。
$ sh -c 'var=abcde; echo "${var%${var#??}}"'
ab
これは、「最小の接頭辞」パラメーター展開を使用して最初の2文字(これは部分)を削除し${var#??}、次に「最小の接尾辞」パラメーター展開(${var%部分)を使用して、元の2文字以外のすべての文字列を削除します。値。
この方法は、「シェル=変数が#で始まるかどうかを確認する」という質問に対するこの回答ですでに説明されています。その回答は、ここでの元の質問に適用されるものとは少し異なるコンテキストで使用できる2つの類似したパラメーター拡張メソッドについても説明しています。
システムが(ではなくbash)別のシェルを使用しているが、システムにはがあるbash場合でも、変数bashを使用して呼び出すことにより、の固有の文字列操作を使用できbashます。
strEcho='echo ${str:0:2}' # '${str:2}' if you want to skip the first two characters and keep the rest
bash -c "str=\"$strFull\";$strEcho;"
bash使用します。まだ使用していない場合にのみ呼び出します。
面白くするために、いくつか追加します。複雑すぎて役に立たないのですが、言及されていませんでした。
head -c 2 <( echo 'USCAGoleta9311734.5021-120.1287855805')
echo 'USCAGoleta9311734.5021-120.1287855805' | dd bs=2 count=1 status=none
sed -e 's/^\(.\{2\}\).*/\1/;' <( echo 'USCAGoleta9311734.5021-120.1287855805')
cut -c 1-2 <( echo 'USCAGoleta9311734.5021-120.1287855805')
python -c "print(r'USCAGoleta9311734.5021-120.1287855805'[0:2])"
ruby -e 'puts "USCAGoleta9311734.5021-120.1287855805"[0..1]'
if mystring = USCAGoleta9311734.5021-120.1287855805
print substr(mystring,0,2)
米国を印刷します
ここで、0は開始位置、2はどのように多くの文字を読み取るかです。
awk。最初はわかりませんでした。