sedは4つのスペースを2に変換します


14

どのようにして4つのスペースを2つのスペースに変換しsedますか?出来ますか?

私はこれを見つけましたが、タブをスペースに変換します:

sed -r ':f; s|^(\t*)\s{4}|\1\t|g; t f' file

回答:


13

投稿したスクリプトは、4 * nスペースをnタブに変換します。ただし、それらのスペースの前にタブが付いている場合のみです。

インデントのみで4つのスペースを2つのスペースに置き換えたい場合は、sedで行うことができますが、代わりにPerlをお勧めします。

perl -pe 's{^((?: {4})*)}{" " x (2*length($1)/4)}e' file

sedで:

sed -e 's/^/~/' -e ': r' -e 's/^\( *\)~    /\1  ~/' -e 't r' -e 's/~//' file

indent代わりに使用することもできます。


私が得たNested quantifiers in regex; marked by <-- HERE in m/^( {4}* <-- HERE )/ at -e line 1.
-eddygeek

1
@eddygeekああ、確かに、それと他のいくつかのバグ。gobbledygookを実際のperlコードに置き換えました。
ジル 'SO-悪であるのをやめる'

5

簡単な方法では動作しません:

sed -r 's/ {4}/  /g'

そうでない場合は、失敗した箇所に入力を投稿してください。


1
これは行の先頭に制限されません。そこに固定すると、複数の一致に対して機能しません。そのため、以下のunix.stackexchange.com/a/375200/259620にいます。
オタクマーリン

あなたは2つのスペースと4つのスペースの組み合わせを持っている場合、2の2つのくぼみが4としてカウントされますので、これは...、動作しません
マット・フレッチャー

@aexl:OPによって必要条件ではありませんでした
トール

@mattfletcher:質問は、私はあなたのポイントを参照してくださいに失敗するので、2と4つのスペースを置き換えるについてだった
トール

4

先行スペースのみが変換される場合:

sed 'h;s/[^ ].*//;s/    /  /g;G;s/\n *//'

コメント付き:

sed '
  h; # save a copy of the pattern space (filled with the current line)
     # onto the hold space
  s/[^ ].*//; # remove everything starting with the first non-space
              # from the pattern space. That leaves the leading space
              # characters
  s/    /  /g; # substitute every sequence of 4 spaces with 2.
  G; # append a newline and the hold space (the saved original line) to
     # the pattern space.
  s/\n *//; # remove that newline and the indentation of the original
            # line that follows it'

vimの'ts'設定と:retabコマンドもご覧ください


あなたのvimソリューションを使用して、vimでそのようないくつかのファイルをバッチ編集する方法はありますか?それ以外の場合、マクロを作成する必要があると思いますか?
chrisjlee

'ts':retabは質問に対する解決策ではありませんが、関連しており、全体的な目標の達成に役立つ場合があることに注意してください。あなたができるvim -- *.c:set ts=...そして:argdo retabまたは:argdo retab!'sw'オプションとvimの独自のインデント機能も参照してください。
ステファンシャゼラス

2
sed 's/^\( \+\)\1\1\1/\1\1/' file

これは、先頭のスペースを同じグループの4つのインスタンスに分割し(それらがすべて等しい)、それらをグループの2つのインスタンスのみに置き換えることで機能します。


これは既存のソリューションをどのように改善しますか?
フィリポス

1
奇数のスペースを保持し、先頭の空白のみに影響し、グローバルフラグを必要とせず、置換の両側の任意の数のスペース(またはタブ)を処理するために簡単に調整でき、より複雑なsedコマンドを使用しませんよりカジュアルなユーザーにとっては不快な場合があります。多くの場合と同様に、それが改善されたかどうかはかなり主観的ですが、自分で言うと、スクリプト内でこれを見つけることは、リストされている他のソリューションのいくつかよりもすぐにわかりやすくなります。
マル

面白い。喜んで聞いた。通常、後方参照はグローバルフラグではなく悪と見なされます。ただし、より移植性の高いスクリプトを使用して同じことを簡単に達成できます(回避\+)。ありがとうございました。
フィリポス

1
sed 's/    \{2,4\}\( \{0,1\}[^ ].*\)*/  \1/g' <input

これは、スペースの先頭シーケンスのみを圧縮する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.