0
给定一个由s 和s组成的字符串1
,我的目标是用 1 替换 0,反之亦然。例子:
输入
111111100000000000000
预期输出
000000011111111111111
我尝试了以下sed
命令,但没有成功
echo '111111100000000000000' | sed -e 's/0/1/g ; s/1/0/g'
000000000000000000000
我缺少什么?
答案1
您可以使用tr
为此,其主要目的是字符翻译:
echo 111111100000000000000 | tr 01 10
您的sed
命令将所有 0 替换为 1,从而生成一个仅包含 1 的字符串(原始 1 和所有替换的 0),然后将所有 1 替换为 0,从而生成一个仅包含 0 的字符串。
在长流上,tr
比 更快sed
;对于 100MiB 文件:
$ time tr 10 01 < bigfileof01s > /dev/null
tr 10 01 < bigfileof01s > /dev/null 0.07s user 0.03s system 98% cpu 0.100 total
$ time sed y/10/01/ < bigfileof01s > /dev/null
sed y/10/01/ < bigfileof01s > /dev/null 3.91s user 0.11s system 99% cpu 4.036 total
答案2
虽然tr
是适合这项工作的工具sed
您可以使用y
(音译)命令而不是(替换)命令来完成此s
操作:
$ echo '111111100000000000000' | sed 'y/01/10/'
000000011111111111111
y
基本上是sed
- 的内部实现tr
- 以及暗示的所有开销。
答案3
一个办法是echo "111111100000000000000" | sed 's/1/2/g;s/0/1/g;s/2/0/g'
答案4
如果您的字符串仅包含一行并且仅由 0 和 1 组成,那么您可以使用此
echo "111111100000000000000" |
perl -e 'while (read(STDIN, $b, 1)) { print chr(ord($b) ^ 1); } print "\n";'
如果字符串可以包含多行,则只需更改perl -e
为perl -ne
并更改读取字节的方式(因为read
需要文件句柄)
echo -e "111111100000000000000\n0001111010101" |
perl -ne 'while (/(.)/g) { print chr(ord($1)^1) } print "\n"'
然而,这样每一行都被分成一个字符串,因此对于大文件来说可能不是很有效。在这种情况下,需要进行一些检查
echo "122111111034000000000abc0000" | perl -e 'while (read(STDIN, $b, 1)) {
print ($b eq '0' or $b eq '1' ? chr(ord($b) ^ 1) : $b) } print "\n";'
正如您所看到的,这种方式也适用于包含'0'
和以外的字符的字符串'1'