これは本当に単純なはずですが、何らかの理由で機能しません。
sed -i.bak -E 's/\t/ /' file.txt
タブ文字を置き換える代わりに、t
文字を置き換えます。私はこれについて考えられるすべてのバリエーションを試してみました。引用などで遊んでみました。Googleで見つけた 他のすべての人 と非常によく似た式を使用していて、それらはうまく機能しているようです。
-E
はOS Xのものです。この失敗はOS Xのsed
の奇妙な癖の結果かもしれないと思ったので、Rubyも(-i
なしで)試してみました。同じ結果を得た:
Ruby -pe '$_.gsub!(/\t/," ")' < file.txt > file.new
OS XとiTermでBash 3.2.51を使用していますが、どれがどれほどひどく関連しているのかはわかりません。奇妙な環境変数は設定していませんが、関連があると思われるものは投稿できます。
何が悪いのでしょうか?
[〜#〜] update [〜#〜]:他の間違いをしたか、 Rubyバージョンを試したときのタイプミス。Gillesはそれがは動作すると(そして私は彼に私を間違って操らせた!)何が起こったのかはわかりませんが、それは私の間違いだったに違いありません。
Sedのタブ文字の構文\t
は標準ではありません。そのエスケープは GNU sed拡張 です。多くの人がGNU sed(これは非組み込みLinuxのsed実装です)を使用しているため、それを使用する多くの例がオンラインで見つかります。しかし OS X sed 、他の* BSD sedと同様に、タブの\t
をサポートせず、代わりに\t
を、バックスラッシュの後にt
を意味するものとして扱います。
次のような多くのソリューションがあります。
リテラルのタブ文字を使用します。
sed -i.bak 's/ / /' file.txt
tr
またはprintf
を使用してタブ文字を生成します。
sed -i.bak "s/$(printf '\t')/ /" file.txt
sed -i.bak "s/$(echo a | tr 'a' '\t')/ /" file.txt
Bashの バックスラッシュエスケープを許可する文字列構文 を使用します。
sed -i.bak $'s/\t/ /' file.txt
Perl、PythonまたはRubyを使用します。投稿したRubyスニペットは機能します。
Bash固有の quoting を使用すると、Cのように文字列を使用できるため、実際のタブ文字がエスケープシーケンスではなくsedに渡されます。
sed -i.bak -E $'s/\t/ /' file.txt
sed -i $'s/\t/ /g' file.txt
oS Xで動作し、Linuxで常に使用するコマンドと同じです。
前述のように、すべてのsed
実装が\t
の表記を水平タブとしてサポートしているわけではありません。
あなたは簡単にあなたの代わりを達成することができます:
Perl -pi.old -e 's{\t+}{ }g' file.txt
これにより、元のファイルを「* .old」として保持するin-situ置換が実行されます。 Perlでは、従来の/
の代替区切り文字を使用して、式をより読みやすくすることができます(つまり、「つまようじを傾ける」症候群がありません)。
+
は、タブ文字の1つ以上の繰り返しが置換されることを示しています。 g
修飾子は、各行の終わり全体でグローバル置換を有効にします。
bash
またはzsh
をシェルとして要求しても問題ない場合、これは私が考えることができる最も簡単な解決策です。
sed "s/$(echo -n -e "\t")/ /" file.txt
ただし、echo
フラグ(-n
および-e
)はPOSIXでは定義されていないため、POSIX準拠のシェルはこれらのフラグを理解する必要はありませんが、互換性の理由から多くのフラグが理解されます。
echo
内でsed
を使用することもできます。
sed -i "s/$(echo '\t')//g"
より強力なsed
が必要な場合(サポート\t
以上)OS Xの場合よりも、 GNU sed をインストールします。