Jawaban:
Dengan GNU sed
:
sed 's/./\&&/2g'
( s
ubstitute setiap ( g
) karakter ( .
) dengan sama ( &
) didahului dengan &
( \&
) tetapi hanya dimulai dari kemunculan kedua ( 2
)).
Mudah dibawa:
sed 's/./\&&/g;s/&//'
(ganti setiap kejadian, tetapi kemudian hapus yang pertama &
yang tidak kita inginkan).
Dengan beberapa awk
implementasi (bukan POSIX karena perilaku tidak ditentukan untuk FS kosong):
awk -F '' -v OFS="&" '{$1=$1;print}'
(dengan gawk
dan beberapa awk
implementasi lainnya , pemisah bidang kosong membagi catatan ke dalam konstituen karakternya . Pemisah bidang keluaran ( OFS
) diatur ke &
. Kami menetapkan nilai untuk $1
(itu sendiri) untuk memaksa catatan untuk dibuat ulang dengan pemisah bidang baru sebelum mencetaknya, NF=NF
juga berfungsi dan sedikit lebih efisien di banyak implementasi awk tetapi perilaku ketika Anda melakukannya saat ini tidak ditentukan oleh POSIX).
perl
:
perl -F -lape '$_=join"&",@F'
( -pe
menjalankan kode untuk setiap baris, dan mencetak hasilnya ( $_
); -l
strip dan menambahkan kembali akhir baris secara otomatis; -a
diisi @F
dengan input split pada pembatas yang ditetapkan -F
, yang di sini adalah string kosong. Hasilnya adalah untuk membagi setiap karakter menjadi @F
, kemudian gabungkan dengan '&', dan cetak garisnya.)
Kalau tidak:
perl -pe 's/(?<=.)./&$&/g'
(ganti setiap karakter asalkan diawali oleh karakter lain (lihat-belakang operator regexp (? <= ...))
Menggunakan zsh
operator shell:
in=12345
out=${(j:&:)${(s::)in}}
(Sekali lagi, pisah pada pemisah bidang kosong menggunakan s::
bendera ekspansi parameter, dan bergabung dengan &
)
Atau:
out=${in///&} out=${out#?}
(ganti setiap kemunculan yang tidak ada (jadi sebelum setiap karakter) dengan &
menggunakan ${var//pattern/replacement}
operator ksh (meskipun dalam ksh
pola kosong berarti sesuatu yang lain, namun sesuatu yang lain, saya tidak yakin apa yang ada di dalamnya bash
), dan lepaskan yang pertama dengan ${var#pattern}
stripping POSIX operator).
Menggunakan ksh93
operator shell:
in=12345
out=${in//~(P:.(?=.))/\0&}
( ~(P:perl-like-RE)
menjadi operator ksh93 glob untuk menggunakan ekspresi reguler seperti perl (berbeda dari perl atau PCRE), (?=.)
menjadi operator yang melihat ke depan: ganti karakter asalkan diikuti oleh karakter lain dengan sendirinya ( \0
) dan &
)
Atau:
out=${in//?/&\0}; out=${out#?}
(ganti setiap karakter ( ?
) dengan &
dan dirinya sendiri ( \0
), dan kami menghapus yang superflous)
Menggunakan bash
operator shell:
shopt -s extglob
in=12345
out=${in//@()/&}; out=${out#?}
(sama seperti zsh
's, kecuali bahwa Anda perlu @()
ada (operator ksh gumpal yang Anda butuhkan extglob
dalam bash
)).
awk -F '' -v OFS="&" 'NF=NF'
Utilitas Unix:
fold -w1|paste -sd\& -
Dijelaskan:
"fold -w1"
- akan membungkus setiap karakter input ke barisnya sendiri
lipat - bungkus setiap jalur input agar sesuai dengan lebar yang ditentukan
-w, --width = WIDTH gunakan kolom WIDTH dan bukan 80
%echo 12345|fold -w1
1
2
3
4
5
"paste -sd\& -"
- akan menggabungkan garis input bersama, menggunakan &
sebagai pemisah
tempel - gabungkan baris file
-s, --serial paste satu file sekaligus bukan secara paralel
-d, --delimiters = LIST menggunakan kembali karakter dari LIST alih-alih TAB
%fold -w1|paste -sd\& -
1&2&3&4&5
(Perhatikan bahwa jika input berisi beberapa baris, mereka akan bergabung dengan &
)
echo "abcdeéèfg" | fold -1 | paste -sd\& -
sed
.
sed
jawaban bagus di bawah ini. Dan saya tidak melihat ada salahnya menunjukkan bagaimana tugas itu dapat diselesaikan dengan cara lain.
"-w"
, thx! "-"
, pada gilirannya, tidak diperlukan If no file operands are specified, the standard input shall be used
sed 's/\B/\&/g'
\ B - Cocok di mana saja tetapi pada batas kata; itu cocok jika karakter di sebelah kiri dan karakter di sebelah kanan adalah karakter "kata" atau "non-kata".
Informasi: Manual sed GNU, ekstensi ekspresi reguler .
Pengujian:
sed 's/\B/\&/g' <<< '12345'
1&2&3&4&5
Ini akan sedikit lebih lambat dari beberapa jawaban lain, tetapi cukup jelas:
echo 12345 | perl -lnE 'say join "&", split //'
Ini cara lain. Bagian pertama dari ekspresi sed menangkap setiap karakter kemudian menggantikannya dengan karakter dan ampersand. Bagian kedua menghapus ampersand dari ujung garis.
echo 12345 | sed -r 's/(.)/\1\&/g;s/\&$//g'
1&2&3&4&5
Bekerja pada karakter multibyte juga.
sed
dua kali, sebuah sed
skrip mungkin memiliki beberapa perintah:sed -r 's/(.)/\1\&/g; s/\&$//g'
012345
input