Misalnya, diberikan:
USCAGoleta9311734.5021-120.1287855805
Saya ingin mengekstrak hanya:
US
Misalnya, diberikan:
USCAGoleta9311734.5021-120.1287855805
Saya ingin mengekstrak hanya:
US
Jawaban:
Mungkin metode yang paling efisien, jika Anda menggunakan bash
shell (dan Anda tampaknya, berdasarkan komentar Anda), adalah menggunakan varian sub-string dari perluasan parameter:
pax> long="USCAGol.blah.blah.blah"
pax> short="${long:0:2}" ; echo "${short}"
US
Ini akan ditetapkan short
menjadi dua karakter pertama dari long
. Jika long
lebih pendek dari dua karakter, short
akan identik dengannya.
Metode dalam shell ini biasanya lebih baik jika Anda akan melakukannya banyak (seperti 50.000 kali per laporan seperti yang Anda sebutkan) karena tidak ada overhead pembuatan proses. Semua solusi yang menggunakan program eksternal akan mengalami overhead tersebut.
Jika Anda juga ingin memastikan panjang minimum , Anda dapat menambahkannya terlebih dahulu dengan sesuatu seperti:
pax> long="A"
pax> tmpstr="${long}.."
pax> short="${tmpstr:0:2}" ; echo "${short}"
A.
Ini akan memastikan bahwa apa pun yang panjangnya kurang dari dua karakter dilapisi di sebelah kanan dengan titik (atau yang lainnya, hanya dengan mengubah karakter yang digunakan saat membuat tmpstr
). Tidak jelas apakah Anda membutuhkan ini, tetapi saya pikir saya akan memasukkannya untuk kelengkapan.
Karena itu, ada sejumlah cara untuk melakukan ini dengan program eksternal (seperti jika Anda tidak memiliki bash
tersedia untuk Anda), beberapa di antaranya adalah:
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/')
Dua pertama (cut
dan head
) identik untuk string satu baris - pada dasarnya keduanya hanya mengembalikan dua karakter pertama. Mereka berbeda dalam hal itu cut
akan memberi Anda dua karakter pertama dari setiap baris danhead
akan memberi Anda dua karakter pertama dari keseluruhan masukan
Yang ketiga menggunakan fungsi awk
sub-string untuk mengekstrak dua karakter pertama dan yang keempat menggunakan sed
grup tangkap (menggunakan()
dan \1
) untuk menangkap dua karakter pertama dan mengganti seluruh baris dengan mereka. Keduanya mirip cut
- keduanya memberikan dua karakter pertama dari setiap baris dalam masukan.
Tidak ada yang penting jika Anda yakin masukan Anda adalah satu baris, semuanya memiliki efek yang sama.
printf '%s'
daripada echo
jika ada karakter aneh dalam string: stackoverflow.com/a/40423558/895245 Untuk POSIX yang terobsesi: head -c
bukan POSIX, cut -c
dan awk substr
, sed \1
tidak yakin.
cara termudah adalah
${string:position:length}
Di mana ini mengekstrak $length
substring dari $string
pada $position
.
Ini adalah bash bawaan sehingga awk atau sed tidak diperlukan.
Anda mendapatkan beberapa jawaban bagus dan saya akan memilih Bash bawaan sendiri, tetapi karena Anda bertanya tentang sed
dan awk
dan ( hampir ) tidak ada orang lain yang menawarkan solusi berdasarkan jawaban tersebut , saya menawarkan ini kepada Anda:
echo "USCAGoleta9311734.5021-120.1287855805" | awk '{print substr($0,0,2)}'
dan
echo "USCAGoleta9311734.5021-120.1287855805" | sed 's/\(^..\).*/\1/'
Yang awk
satu seharusnya cukup jelas, tapi berikut penjelasannya sed
:
substr($0,1,2)
.
Jika Anda ikut bash
, Anda dapat mengatakan:
bash-3.2$ var=abcd
bash-3.2$ echo ${var:0:2}
ab
Ini mungkin yang Anda butuhkan…
Grep saja:
echo 'abcdef' | grep -Po "^.." # ab
-P
opsi untuk membuatnya lebih pendek. Semua regex akan memahami pola itu.
Anda dapat menggunakan printf
:
$ original='USCAGoleta9311734.5021-120.1287855805'
$ printf '%-.2s' "$original"
US
Terlambat memang tapi ini dia
sed 's/.//3g'
Atau
awk NF=1 FPAT=..
Atau
perl -pe '$_=unpack a2'
Jika Anda ingin menggunakan skrip shell dan tidak bergantung pada ekstensi non-posix (seperti yang disebut bashisme), Anda dapat menggunakan teknik yang tidak memerlukan alat eksternal forking seperti grep, sed, cut, awk, dll., Yang kemudian buat skrip Anda kurang efisien. Mungkin efisiensi dan portabilitas posix tidak penting dalam kasus penggunaan Anda. Tetapi jika itu (atau hanya sebagai kebiasaan baik), Anda dapat menggunakan metode opsi perluasan parameter berikut untuk mengekstrak dua karakter pertama dari variabel shell:
$ sh -c 'var=abcde; echo "${var%${var#??}}"'
ab
Ini menggunakan perluasan parameter "awalan terkecil" untuk menghapus dua karakter pertama (ini adalah ${var#??}
bagian), kemudian perluasan parameter "akhiran terkecil" (${var%
bagian) untuk menghapus string semua-kecuali-dua-karakter-pertama dari aslinya nilai.
Metode ini sebelumnya dijelaskan dalam jawaban ini untuk pertanyaan "Shell = Periksa apakah variabel dimulai dengan #". Jawaban itu juga menjelaskan beberapa metode perluasan parameter serupa yang dapat digunakan dalam konteks yang sedikit berbeda dengan metode yang diterapkan pada pertanyaan awal di sini.
Jika sistem Anda menggunakan shell yang berbeda (bukan bash
), tetapi sistem Anda memilikinya bash
, maka Anda masih dapat menggunakan manipulasi string inheren bash
dengan memanggil bash
dengan variabel:
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
jika Anda belum menggunakannya.
Hanya untuk kesenangan saya akan menambahkan beberapa, meskipun mereka terlalu rumit dan tidak berguna, mereka tidak disebutkan:
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]'
jika mystring = USCAGoleta9311734.5021-120.1287855805
print substr(mystring,0,2)
akan mencetak AS
dimana 0 adalah posisi awal dan 2 adalah bagaimana karakter untuk dibaca
awk
. Maaf, awalnya saya tidak tahu.
Apakah ini yang Anda kejar?
my $string = 'USCAGoleta9311734.5021-120.1287855805';
my $first_two_chars = substr $string, 0, 2;
ref: substr
perl -e 'print substr $ARGV[0], 0, 2' 'USCAGoleta9311734.5021-120.1287855805'