Câu trả lời:
Với GNU sed
:
sed 's/./\&&/2g'
( s
ubstolarship every ( g
) character ( .
) với cùng ( &
) đứng trước &
( \&
) nhưng chỉ bắt đầu từ lần xuất hiện thứ hai ( 2
)).
Có thể:
sed 's/./\&&/g;s/&//'
(thay thế mọi lần xuất hiện, nhưng sau đó xóa cái đầu tiên &
mà chúng ta không muốn).
Với một số awk
triển khai (không phải POSIX vì hành vi không được chỉ định cho một FS trống):
awk -F '' -v OFS="&" '{$1=$1;print}'
(cùng với gawk
một vài cách awk
triển khai khác , một dấu tách trường trống sẽ phân tách các bản ghi thành các thành phần ký tự của nó . Dấu tách trường đầu ra ( OFS
) được đặt thành &
. Chúng tôi gán một giá trị cho $1
(chính nó) để buộc bản ghi được tạo lại bằng dấu tách trường mới trước khi in, nó NF=NF
cũng hoạt động và hiệu quả hơn một chút trong nhiều triển khai awk nhưng hành vi khi bạn làm điều đó hiện không được xác định bởi POSIX).
perl
:
perl -F -lape '$_=join"&",@F'
( -pe
Chạy mã cho mỗi dòng, và in kết quả ( $_
); -l
dải và tái bổ sung kết thúc dòng tự động; -a
populates @F
với chia đầu vào tập delimiter trong -F
., Mà ở đây là một chuỗi rỗng Kết quả là chia mỗi nhân vật vào @F
, sau đó nối chúng với '&' và in dòng.)
Cách khác:
perl -pe 's/(?<=.)./&$&/g'
(thay thế mọi ký tự được cung cấp trước nó bởi một ký tự khác (toán tử regrec đằng sau (? <= ...))
Sử dụng zsh
toán tử shell:
in=12345
out=${(j:&:)${(s::)in}}
(một lần nữa, phân tách trên một dấu tách trường trống bằng s::
cờ mở rộng tham số và nối với &
)
Hoặc là:
out=${in///&} out=${out#?}
(thay thế mọi sự cố không xảy ra (vì vậy trước mỗi ký tự) bằng &
cách sử dụng ${var//pattern/replacement}
toán tử ksh (mặc dù trong ksh
một mẫu trống có nghĩa là một cái gì đó khác, và một cái gì đó khác, tôi không chắc chắn cái gì trong bash
) và loại bỏ cái đầu tiên với ${var#pattern}
tước POSIX nhà điều hành).
Sử dụng ksh93
toán tử shell:
in=12345
out=${in//~(P:.(?=.))/\0&}
( ~(P:perl-like-RE)
là toán tử toàn cầu ksh93 để sử dụng các biểu thức chính quy giống như perl (khác với perl's hoặc PCRE), (?=.)
là toán tử nhìn về phía trước: thay thế một ký tự được cung cấp bởi một ký tự khác bằng chính nó ( \0
) và &
)
Hoặc là:
out=${in//?/&\0}; out=${out#?}
(thay thế mọi ký tự ( ?
) bằng &
và chính nó ( \0
) và chúng tôi xóa ký tự thừa)
Sử dụng bash
toán tử shell:
shopt -s extglob
in=12345
out=${in//@()/&}; out=${out#?}
(giống như zsh
's, ngoại trừ việc bạn cần @()
có (một nhà điều hành ksh glob mà bạn cần extglob
trong bash
)).
awk -F '' -v OFS="&" 'NF=NF'
Tiện ích Unix:
fold -w1|paste -sd\& -
Giải thích:
"fold -w1"
- sẽ bọc một ký tự đầu vào vào dòng riêng của nó
gấp - bọc từng dòng đầu vào để phù hợp với chiều rộng quy định
-w, - thong = WIDTH sử dụng các cột WIDTH thay vì 80
%echo 12345|fold -w1
1
2
3
4
5
"paste -sd\& -"
- sẽ hợp nhất các dòng đầu vào với nhau, sử dụng &
như một dấu phân cách
dán - hợp nhất các dòng của tập tin
-s, --serial dán một tệp cùng một lúc thay vì song song
-d, --d006wr = LIST sử dụng lại các ký tự từ LIST thay vì TAB
%fold -w1|paste -sd\& -
1&2&3&4&5
(Lưu ý rằng nếu đầu vào chứa một vài dòng, chúng sẽ được nối với &
)
echo "abcdeéèfg" | fold -1 | paste -sd\& -
sed
.
sed
câu trả lời tốt có sẵn dưới đây. Và tôi không thấy bất kỳ tác hại nào trong việc chứng minh làm thế nào nhiệm vụ có thể được giải quyết bằng các phương tiện khác.
sed 's/\B/\&/g'
\ B - Phù hợp ở mọi nơi nhưng trên một ranh giới từ; đó là phù hợp nếu ký tự bên trái và ký tự bên phải là cả hai ký tự Từ trong một từ hoặc cả hai ký tự không chữ.
Thông tin: Hướng dẫn sử dụng GNU sed, phần mở rộng biểu thức chính quy .
Kiểm tra:
sed 's/\B/\&/g' <<< '12345'
1&2&3&4&5
Điều này sẽ chậm hơn một chút so với một số câu trả lời khác, nhưng nó khá rõ ràng:
echo 12345 | perl -lnE 'say join "&", split //'
Đây là một cách khác. Phần đầu tiên của biểu thức sed bắt giữ mọi nhân vật sau đó thay thế nó bằng ký tự và ký hiệu. Phần thứ hai loại bỏ ký hiệu và từ cuối dòng.
echo 12345 | sed -r 's/(.)/\1\&/g;s/\&$//g'
1&2&3&4&5
Hoạt động trên các nhân vật đa nhân cũng vậy.
sed
hai lần, một sed
tập lệnh có thể có một số lệnh:sed -r 's/(.)/\1\&/g; s/\&$//g'
012345
đầu vào