Sté*_*las 26

使用 GNU sed

sed 's/./\&&/2g'
Run Code Online (Sandbox Code Playgroud)

substitute每(g)字符(.)具有相同的(&前面有)&\&),但只有来自第二发生开始(2))。

便携:

sed 's/./\&&/g;s/&//'
Run Code Online (Sandbox Code Playgroud)

(替换每一次出现,然后删除&我们不想要的第一个)。

对于某些awk实现(不是 POSIX,因为未指定空 FS 的行为):

awk -F '' -v OFS="&" '{$1=$1;print}'
Run Code Online (Sandbox Code Playgroud)

(使用gawk和其他一些awk实现,空字段分隔符将记录拆分为其字符成分输出字段分隔符( OFS) 设置为&。我们为$1(本身)分配一个值以强制使用新的字段分隔符重新生成记录在打印之前,它NF=NF也可以工作并且在许多 awk 实现中效率更高,但是当前 POSIX 未指定执行此操作时的行为)。

perl

perl -F -lape '$_=join"&",@F' 
Run Code Online (Sandbox Code Playgroud)

(-pe为每一行运行代码,并打印结果 ( $_);自动-l剥离并重新添加行尾;在 中设置的分隔符上使用输入拆分-a填充,这里是一个空字符串。结果是将每个字符拆分为,然后用 '&' 将它们连接起来,并打印该行。)@F-F@F

或者:

perl -pe 's/(?<=.)./&$&/g' 
Run Code Online (Sandbox Code Playgroud)

(替换每个字符,前提是它前面有另一个字符(后视正则表达式运算符 (?<=...))

使用zshshell 运算符:

in=12345
out=${(j:&:)${(s::)in}}
Run Code Online (Sandbox Code Playgroud)

(再次,使用s::参数扩展标志在空字段分隔符上拆分,并加入&

或者:

out=${in///&} out=${out#?}
Run Code Online (Sandbox Code Playgroud)

&使用${var//pattern/replacement}ksh 操作符替换所有没有出现的内容(所以在每个字符之前)(尽管在ksh空模式中意味着其他内容,但还有其他内容,我不确定中的内容bash),并使用 POSIX${var#pattern}剥离删除第一个操作员)。

使用ksh93shell 运算符:

in=12345
out=${in//~(P:.(?=.))/\0&}
Run Code Online (Sandbox Code Playgroud)

~(P:perl-like-RE)作为 ksh93 glob 运算符使用类似 perl 的正则表达式(尽管与 perl 或 PCRE 不同),(?=.)作为前瞻运算符:替换一个字符,前提是它后面跟着另一个字符本身(\0)和&

或者:

out=${in//?/&\0}; out=${out#?}
Run Code Online (Sandbox Code Playgroud)

(将每个字符 ( ?)替换为&和它本身 ( \0),我们删除多余的字符)

使用bashshell 运算符:

shopt -s extglob
in=12345
out=${in//@()/&}; out=${out#?}
Run Code Online (Sandbox Code Playgroud)

(一样zsh的,只是你需要@()有(您需要一个KSH水珠运营商extglobbash))。

  • @AFSHIN,这不适用于 `012345` 输入 (2认同)
  • @StéphaneChazelas 很棒,谢谢。在复杂的文档中搜索 sed 之类的东西是一门艺术,因此拥有一些动手示例是学习您以前从未见过的新内容的好方法。 (2认同)

zep*_*lin 15

Unix 实用程序:

fold -w1|paste -sd\& -
Run Code Online (Sandbox Code Playgroud)

解释:

"fold -w1" - 将每个输入字符包装到它自己的行

fold - 包裹每个输入行以适应指定的宽度

-w, --width=WIDTH 使用 WIDTH 列而不是 80

%echo 12345|fold -w1
1
2
3
4
5
Run Code Online (Sandbox Code Playgroud)

"paste -sd\& -"- 将输入行合并在一起,&用作分隔符

粘贴 - 合并文件行

-s, --serial 一次粘贴一个文件而不是并行粘贴

-d, --delimiters=LIST 重用 LIST 中的字符而不是制表符

%fold -w1|paste -sd\& -
1&2&3&4&5
Run Code Online (Sandbox Code Playgroud)

(请注意,如果输入包含多行,它们将与&

  • @Alexander - 这是真的,下面有许多很好的`sed` 答案。而且我认为演示如何通过其他方式解决任务没有任何害处。 (6认同)
  • 这个问题特别是关于`sed`。 (5认同)
  • @Arrow 很可能您只是在使用 [buggy](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=721324) _coreutils_ 版本的 _fold_,它没有完整的 Unicode 支持。BSD 折叠、RedHat 补丁版本的 _coreutils_(即 Fedora 或 CentOS)以及它的 BusyBox 实现,可以很好地处理 Unicode。 (3认同)
  • 多字节字符失败。试试`echo "abcdeéèfg" | 折叠 -1 | 粘贴 -sd\&amp; -` (2认同)

Min*_*Max 9

sed 's/\B/\&/g'
Run Code Online (Sandbox Code Playgroud)

\B - 匹配任何地方,但在单词边界上;也就是说,如果左边的字符和右边的字符都是“单词”字符或都是“非单词”字符,则匹配。

信息: GNU sed 手册,正则表达式扩展

测试:

sed 's/\B/\&/g' <<< '12345'
1&2&3&4&5
Run Code Online (Sandbox Code Playgroud)

  • 有趣的想法,但问题并不是说字符串不包含空格、点或任何可能构成单词边界的东西。它只是说“字符之间”,应该被解释为“任何字符”。 (5认同)