0
sと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
仕事に適したツールです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
文字列が 1 行だけで 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'