Saya memiliki string yang ingin saya manipulasi. String adalah H08W2345678
bagaimana saya bisa memanipulasinya sehingga outputnya adil W2345678
?
Demikian pula jika saya ingin H08W2345678
mengeluarkan 4 karakter terakhir dari sehingga saya mendapatkan H08W234
bagaimana saya melakukan ini?
bash
shell
text-processing
sed
3kstc
sumber
sumber
sed
?H08W2345678
dan perlu untuk memanipulasinya hinggaW2345678
Nilai ini dengan datum lain akan dimasukkan ke dalam email yang dikirim. Email Anda akan dilakukan dengan cron.awk
ing itu. Saya membuat array dan kemudian memodifikasi setiap elemen dalam array (semuanya berbeda - yaitu mengubah timestaimp Epoch dalam hitungan detik menjadi tanggal dll.)printf %s\\n "XX,H08W2345678,YY" | awk -F, '{print substr($2, 4); print substr($2, 1, length($2)-4)}'
Jawaban:
Hanya menggunakan bash (atau dari
ksh93
mana sintaks itu berasal atauzsh
):Lihat wiki Wooledge untuk informasi lebih lanjut tentang manipulasi string .
sumber
"${string:0:${#string}-4}"
bekerja dalam versi bash 4.1 selama panjangnya$string
setidaknya 4.abc-e
, di mana, ketika Anda menjatuhkan tiga karakter pertama, Anda yang tersisa-e
(karenaecho -e
tidak melakukan apa yang Anda inginkan).sed 's/^.\{3\}//'
akan menemukan tiga karakter pertama dengan^.\{3\}
dan mengganti dengan yang kosong. Di sini^.
akan cocok dengan karakter apa pun di awal string (^
menunjukkan awal string) dan\{3\}
akan cocok dengan pola sebelumnya tepat 3 kali. Jadi,^.\{3\}
akan cocok dengan tiga karakter pertama.Demikian pula,
sed 's/.\{4\}$//'
akan mengganti empat karakter terakhir dengan kosong ($
menunjukkan akhir dari string).sumber
's/^.\{3\}//'
dan's/.\{4\}$//'
karena saya masih belajar sedikit, terima kasih banyak...
bukan.\{3\}
karena (saya) lebih mudah untuk dibaca:sed -e 's/^...//' -e 's/....$//'
atau dalam ekspresi tunggal dengan silih bergantinya:sed -r 's/^...|....$//g'
. Jika lebih dari beberapa karakter untuk dihapus, maka saya akan menggunakan/.\{17}\/
ekspresi bukan/.............../
.-e
atau-n
. Tentu saja, arti dari “drop 4 karakter terakhir” tidak terdefinisi untuk string pendek dari 4 karakter, tetapi, jika seseorang ingin beradaptasi ini untuk menjatuhkan pertama atau terakhir satu karakter, itu bisa meledak.Jika Anda memiliki file di mana setiap baris adalah string sebelas karakter (atau apa pun) yang ingin Anda potong,
sed
adalah alat untuk digunakan. Tidak apa-apa untuk memanipulasi string tunggal, tetapi itu berlebihan. Untuk string tunggal, jawaban Jason mungkin yang terbaik, jika Anda memiliki akses ke bash versi 4.2 atau lebih tinggi. Namun, dan sintaksis tampaknya unik untuk bash (well, bash, ksh93, mksh, dan zsh) - Saya tidak melihatnya di Spesifikasi Basis Grup Terbuka untuk Bahasa Perintah Shell . Jika Anda terjebak dengan shell yang mendukung POSIX yang tidak mendukung ekspansi substring (ekstraksi), Anda dapat menggunakan${parameter:offset}
${parameter:offset:length}
menggunakan
printf
alih-alihecho
untuk menjaga terhadap string sepertiabc-e
, di mana, ketika Anda menjatuhkan tiga karakter pertama, Anda dibiarkan-e
(danecho -e
tidak melakukan apa yang Anda inginkan).Dan, jika Anda tidak menggunakan shell Bourne-family sama sekali (atau Anda menggunakan sistem kuno, pra-POSIX), ini akan tetap berfungsi:
Ruang terkemuka tambahan untuk menghindari masalah dengan nilai-nilai
$string
yang sebenarnyaexpr
operator (misalnya,+
,/
,index
ataumatch
) atau pilihan (misalnya,--
,--help
atau--version
).sumber
X
; misalnyaexpr "X$string" : 'X...\(.*\)'
,. IMO, itu lebih mudah dibaca dan dimengerti. Apakah ada masalah dengan itu, atau ada alasan untuk memilih ruang? (3) Hari ini saya belajar bahwaexpr + "$string" : '...\(.*\)'
sekarang berhasil. Saya tidak ingat itu dari 40 tahun yang lalu; apakah cukup banyak digunakan agar aman untuk direkomendasikan? (4) Anda melewatkan sebuah catatan tentang jawaban jasonwryan dan sebuah pilihan pada jawaban heemayl.expr +
hanya GNU (tidak akan berfungsi pada Solaris atau FreeBSD AFAICS). Saya menggunakan ruang alih-alih x karena lebih kecil kemungkinannya bahwa beberapaexpr
implementasi akan memiliki operator yang memulai dengan ruang daripada denganx
dan juga karena lebih kecil kemungkinannya ada elemen penyatuan yang dimulai dengan ruang daripada denganx
. Tapi kemudian saya menyadari itu mungkin bukan pilihan yang baikexpr " $a" "<" " $b"
untuk perbandingan string karena beberapa implementasi akhirnya melakukan perbandingan numerik ketika$a
/$b
terlihat seperti angka. Mungkinexpr "@@$a"...
atauexpr "x $a"
bisa lebih aman.Dengan:
Mencocokkan 3 atau 4 karakter tampaknya sederhana (untuk sebagian besar shell):
Untuk cangkang yang lebih lama (seperti cangkang Bourne), gunakan:
Jika diperlukan jumlah karakter, gunakan:
Tentu saja, regex tersebut juga berfungsi dengan sed, awk, dan bash 3.0+:
sumber
sumber
cut
itu jauh lebih elegan daripada apa pun yang ada di halaman ini.