web-dev-qa-db-ja.com

先頭のタブ(一部の空白文字の後のタブを含む)のみを置き換える方法は?

タブまたはスペース、あるいはその両方でインデントされているファイルがいくつかあります。先頭のタブをスペースに変換したい(1つのタブから4つのスペース)。これには、いくつかの先頭のスペースの後のタブが含まれます。以下は、いくつかの入力行と期待される結果の例です。

 + ----- + --------------- + ----------------- + 
 |いいえ。オリジナルライン|期待される結果| 
 + ----- + --------------- + ----------------- + 
 | 1 | \t␣xxx| ␣␣␣␣␣xxx| 
 | 2 | ␣␣␣\ txxx | ␣␣␣␣␣␣␣xxx| 
 | 3 | \t␣\ txxx | ␣␣␣␣␣␣␣␣␣xxx| 
 | 4 |\tx\txx | ␣␣␣␣x\ txx | 
 + ----- + --------------- + -------------- --- + 

ここでは、スペースとタブが混在している場合に対応できないため、expandコマンドを使用できません。以下に例を示します。

user1@ubuntu$ printf "\t  \txxx" | od -t a
0000000  ht  sp  sp  ht   x   x   x
0000007
user1@ubuntu$ printf "\t  \txxx" | expand -i -t 4 | od -t a
0000000  sp  sp  sp  sp  sp  sp  sp  sp   x   x   x
0000013
user1@ubuntu$ 

ご覧のとおり、元の文字列の2つのスペースは単に削除されています。私の問題を解決する方法は?このサイトで他の同様の質問を読みましたが、それらは私の問題とまったく同じではありません。

2
Just a learner

最初の非スペース文字の前にあるすべてのタブを4つのスペースに置き換えるには、次のことを試してください。

Perl -pe '/^(\s+)/; $k=$1; $k=~s/\t/    /g; s/^\s+/$k/'file > newfile

スクリプトは最初にすべての先頭の空白(スペース、タブ、その他)を検索し、それを$kとして保存します。次に、すべてのタブを$kの4つのスペースに置き換え、最後にすべての先頭の空白を現在の値$kに置き換えます。

スペースとタブのみに制限するには、次の操作を実行できます。

Perl -pe '/^([ \t]+)/; $k=$1; $k=~s/\t/    /g; s/^\s+/$k/'file > newfile

サンプルの文字列で実行すると、これらのソリューションは以下を生成します。

$  printf '\t xxx\n   \txxx\n\t \txxx\n\tx\txx\n'  | Perl -pe '/^(\s+)/; $k=$1; $k=~s/\t/    /g; s/^\s+/$k/' | od -t a
0000000  sp  sp  sp  sp  sp   x   x   x  nl  sp  sp  sp  sp  sp  sp  sp
0000020   x   x   x  nl  sp  sp  sp  sp  sp  sp  sp  sp  sp   x   x   x
0000040  nl  sp  sp  sp  sp   x  ht   x   x  nl
0000052
1
terdon