144

たとえば、次のようになります。

USCAGoleta9311734.5021-120.1287855805

抽出したい:

US
4

15 に答える 15

211

bashシェルを使用している場合(そしてコメントに基づいてそう思われる場合)、おそらく最も効率的な方法は、パラメーター展開のサブストリングバリアントを使用することです。

pax> long="USCAGol.blah.blah.blah"
pax> short="${long:0:2}" ; echo "${short}"
US

これはshort、の最初の2文字に設定されますlonglongが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つ(cuthead)は、1行の文字列と同じです。基本的に、どちらも最初の2文字を返すだけです。それらはcut、各行headの最初の2文字を提供し、入力全体の最初の2文字を提供するという点で異なります。

3つ目は、awkサブ文字列関数を使用して最初の2文字を抽出し、4つ目はsedキャプチャグループ(()およびを使用\1)を使用して最初の2文字をキャプチャし、行全体をそれらに置き換えます。どちらも似ていますcut-入力の各行の最初の2文字を配信します。

入力が1行であることが確実な場合は、それは問題ではありません。すべて同じ効果があります。

于 2009-09-10T14:32:36.890 に答える
71

最も簡単な方法は次のとおりです。

${string:position:length}

これがat$lengthから部分文字列を抽出する場所。$string$position

これはBashに組み込まれているため、awkやsedは必要ありません。

于 2009-09-10T14:31:13.570 に答える
36

あなたはいくつかの良い答えを得ており、私自身は Bash ビルトインを使用したいと思いますが、あなたが尋ねたのでsedawkそして (ほとんど) 他の誰もそれらに基づくソリューションを提供しなかったので、これらを提供します:

echo "USCAGoleta9311734.5021-120.1287855805" | awk '{print substr($0,0,2)}'

echo "USCAGoleta9311734.5021-120.1287855805" | sed 's/\(^..\).*/\1/'

1awkつはかなり明白なはずですが、これについての説明は次のsedとおりです。

  • 「s/」に置き換えます
  • 行頭「^」で始まり、任意の文字「.」が続く任意の文字「..」の 2 つのグループ「()」"*" を 0 回以上繰り返す (一部の特殊文字をエスケープするには、バックスラッシュが必要です)
  • 「/」によって、最初の (そしてこの場合は唯一の) グループの内容 (ここでバックスラッシュは、一致する部分式を参照する特別なエスケープです)
  • 終わり "/"
于 2009-09-10T15:40:31.377 に答える
10

ただgrep:

echo 'abcdef' | grep -Po "^.."        # ab
于 2017-01-02T18:33:50.700 に答える
9

にいる場合はbash、次のように言うことができます。

bash-3.2$ var=abcd
bash-3.2$ echo ${var:0:2}
ab

これはまさにあなたが必要としているものかもしれません…</p>

于 2009-09-10T16:35:06.170 に答える
5

colrm — ファイルから列を削除する

最初の 2 文字を残すには、3 から始まる列を削除するだけです

cat file | colrm 3
于 2009-09-10T15:44:59.073 に答える
2

楽しみのためにいくつか追加しますが、それらは複雑すぎて役に立たないものの、言及されていません。

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]'
于 2020-05-16T01:23:02.600 に答える
0

これはあなたが求めているものかもしれません:

my $string = 'USCAGoleta9311734.5021-120.1287855805';

my $first_two_chars = substr $string, 0, 2;

参照:substr

于 2009-09-10T14:32:55.640 に答える
-1

コード

if mystring = USCAGoleta9311734.5021-120.1287855805

    print substr(mystring,0,2)

米国を印刷します。

ここで、0は開始位置、2は読み取る文字数です。

于 2009-09-10T14:33:14.347 に答える
-1
perl -ple 's/^(..).*/$1/'
于 2009-09-10T14:44:53.530 に答える