Odpowiedzi:
Z GNU sed:
sed 's/./\&&/2g'
( sUbstitute każdy ( g) znak ( .) z tym samym ( &) poprzedzone &( \&), ale dopiero od drugiego wystąpienia ( 2)).
Przenośny:
sed 's/./\&&/g;s/&//'
(zamień każde wystąpienie, ale następnie usuń pierwsze, &którego nie chcemy).
W przypadku niektórych awkimplementacji (nie POSIX, ponieważ zachowanie nie jest określone dla pustego FS):
awk -F '' -v OFS="&" '{$1=$1;print}'
(z gawkkilkoma innymi awkimplementacjami, pusty separator pól dzieli rekordy na składniki znakowe . Separator pól wyjściowych ( OFS) jest ustawiony na &. Przypisujemy wartość do $1(samej), aby wymusić odtworzenie rekordu za pomocą nowego separatora pól przed wydrukowaniem NF=NFdziała również i jest nieco bardziej wydajny w wielu implementacjach awk, ale zachowanie, kiedy to robisz, nie jest obecnie określone przez POSIX).
perl:
perl -F -lape '$_=join"&",@F'
( -peuruchamia kod dla każdego wiersza i wypisuje wynik ( $_); automatycznie -lusuwa paski i ponownie dodaje zakończenia wierszy; -awypełnia @Fsię wprowadzonym podziałem wejściowym w ustawionym ograniczniku -F, który tutaj jest pustym ciągiem. Wynikiem jest podzielenie każdego znaku na @F, następnie połącz je za pomocą „&” i wydrukuj wiersz).
Alternatywnie:
perl -pe 's/(?<=.)./&$&/g'
(zamień każdy znak, pod warunkiem, że poprzedza go inny znak (patrz operator wyrażenia regularnego (? <= ...))
Korzystanie z zshoperatorów powłoki:
in=12345
out=${(j:&:)${(s::)in}}
(ponownie podziel na pusty separator pól przy użyciu s::flagi rozwijania parametrów i połącz się z &)
Lub:
out=${in///&} out=${out#?}
(zastąpić każde wystąpienie nic (tak przed każdym znaku) z &użyciem ${var//pattern/replacement}operatora ksh (choć w kshpustym środki wzór czegoś innego, a jeszcze coś innego, nie jestem pewien, co w bash) i wyjąć pierwszy z POSIX ${var#pattern}stripping operator).
Korzystanie z ksh93operatorów powłoki:
in=12345
out=${in//~(P:.(?=.))/\0&}
( ~(P:perl-like-RE)będąc operatorem globalnym ksh93, który używa wyrażeń regularnych podobnych do perla (różniących się od perla lub PCRE), (?=.)będąc operatorem wybiegającym w przyszłość: zamień znak pod warunkiem, że następuje po nim inny znak ze sobą ( \0) i &)
Lub:
out=${in//?/&\0}; out=${out#?}
(zamień każdy znak ( ?) na &i sama ( \0), a my usuniemy zbędny)
Korzystanie z bashoperatorów powłoki:
shopt -s extglob
in=12345
out=${in//@()/&}; out=${out#?}
(to samo co zsh„s, z wyjątkiem, że trzeba @()tam (operator ksh glob, dla którego trzeba extglobw bash)).
awk -F '' -v OFS="&" 'NF=NF'
Narzędzia uniksowe:
fold -w1|paste -sd\& -
Wyjaśnione:
"fold -w1" - zawinie każdy znak wejściowy do własnej linii
fold - zawiń każdą linię wejściową, aby dopasować ją do określonej szerokości
-w, --width = WIDTH używa kolumn WIDTH zamiast 80
%echo 12345|fold -w1
1
2
3
4
5
"paste -sd\& -"- scali linie wejściowe razem, używając &jako separatora
wklej - scal linie wierszy plików
-s, --serial wklejaj jeden plik na raz zamiast równolegle
-d, --delimiters = LISTA ponownie wykorzystuje znaki z LISTY zamiast TAB
%fold -w1|paste -sd\& -
1&2&3&4&5
(Uwaga: jeśli dane wejściowe zawierają kilka wierszy, zostaną połączone &)
echo "abcdeéèfg" | fold -1 | paste -sd\& -
sed.
sedponiżej znajduje się wiele dobrych odpowiedzi. I nie widzę żadnej szkody w demonstrowaniu, jak zadanie można rozwiązać innymi sposobami.
sed 's/\B/\&/g'
\ B - Pasuje wszędzie, ale na granicy słów; to znaczy pasuje, jeśli znak po lewej stronie i znak po prawej stronie są zarówno znakami „słownymi”, jak i obydwoma znakami „niebędącymi słowami”.
Informacja: Podręcznik GNU sed, rozszerzenia wyrażeń regularnych .
Testowanie:
sed 's/\B/\&/g' <<< '12345'
1&2&3&4&5
To będzie trochę wolniejsze niż niektóre inne odpowiedzi, ale jest całkiem jasne:
echo 12345 | perl -lnE 'say join "&", split //'
Oto inny sposób. Pierwsza część wyrażenia sed przechwytuje każdą postać, a następnie zastępuje ją znakiem i znakiem ampersand. Druga część usuwa znaki handlowe i koniec linii.
echo 12345 | sed -r 's/(.)/\1\&/g;s/\&$//g'
1&2&3&4&5
Działa również na znakach wielobajtowych.
seddwa razy, sedskrypt może mieć kilka poleceń:sed -r 's/(.)/\1\&/g; s/\&$//g'
012345danych wejściowych