스트림에서 0을 1로 또는 그 반대로 바꾸는 가장 빠른 방법은 무엇입니까?

스트림에서 0을 1로 또는 그 반대로 바꾸는 가장 빠른 방법은 무엇입니까?

0s 와 s 로 구성된 문자열이 주어지면 1내 목표는 0을 1로 바꾸거나 그 반대로 바꾸는 것입니다. 예:

입력하다

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만 포함하는 문자열을 생성합니다.

긴 스트림에서는 100MiB 파일 tr보다 빠릅니다 .sed

$ 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작업에 적합한 도구입니다sedy(대체) 명령 대신 (음역) 명령을 사용하여 이 작업을 수행 할 수 있습니다 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 -neread

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'

관련 정보