タブ、スペース、またはその両方にインデントされたいくつかのファイルがあります。先行タブを空白に変換したい(タブ1つを空白4つに)。これには、いくつかの先行スペースの後ろのタブが含まれます。以下は、入力ラインと期待される結果のいくつかの例です。
+----+---+---+ |番号|元の行|予想結果| +----+---+---+ 1 | ␣␣␣␣␣xxx | 2 | ␣␣␣␣␣␣␣xxx | 3 | \t␣\txxx ␣␣␣␣␣␣␣␣␣xxx | 4 | ␣␣␣␣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つのスペースは単に削除されました。私の問題を解決する方法?このサイトで他の同様の質問を読みましたが、私の質問とまったく同じではありません。
答え1
cat -T
sedを使用できます(タブが表示されたときにファイルを表示するために使用されます^I
)。
$ cat -T file
^I abc
^I ^Ixde^Inot
$ sed ':x;s|^\( *\)\t|\1 |;tx' file | cat -T
abc
xde^Inot
残念ながら、asタブの解釈は\t
POSIX仕様ではなくGNU sed拡張です。ただし、この問題を解決できますprintf
Gillesが説明したように使用してください。書き込み:
sed ":x;s|^\( *\)$(printf '\t')|\1 |;tx" file
sedはそこで何をしていますか?
s|^\( *\)\t|\1 |
sedが行の先頭に固定されている0個以上の空白文字が続くタブ文字を見つけると、タブ文字を4つの空白に置き換えます。ペアは、\(\)
ゼロ個以上の前の空白文字で構成される一致グループの発生に分けられます\1
。
tx
交換した場合はラベルに移動します:x
。それ以外の場合は、次の行に進んでください。
答え2
スペース以外の最初の文字の前にあるすべてのタブ文字を4つのスペースに置き換えるには、次のようにします。
perl -pe '/^(\s+)/; $k=$1; $k=~s/\t/ /g; s/^\s+/$k/'file > newfile
スクリプトは最初にすべての先行スペース(スペース、タブ、その他の項目)を見つけます$k
。$k
$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