1つの場所にバイナリではなくファイルの大規模なコレクションがあります。その中にはシャーバンがあり、一部は(説明できない理由で)シャバンの前にスペースがあります。これには以下が含まれます空白行と空白のみの行!
例1:
#!/usr/bin/env foo バー
例2:
#!/usr/bin/env foo バー
例3:
#! /bin/sh -e
例4:
______ /____/___ ____ //_/__\/__\ /__/ / /_/ / /_/ / /_/ \____/\____/ 今日のヒントを含むFooニュース#324: シェルスクリプトファイルの上に #!/bin/sh を入れることを忘れないでください。
私は1と2のようなファイルから先行スペースを削除し、同時に3、特に4(shebangのようなコンテンツが含まれている場合でも)を維持するGNU(Linux)ベースのシステムのためのソリューションを期待しています。
例1と2は次のとおりです。
#!/usr/bin/env foo バー
これまでに失敗した試みは次のとおりです。
最初のステップは、例1-3と4を区別することです。
grep -Pzo '^[ \t\n]+#! ?[ \w/.-]+'
ので動作しません
grep: unescaped ^ or $ not supported with -Pz
。使用
awk
:awk 'BEGIN {ws_check=1} !/[ \t]+/ {ws_check=0} /#! ?[ \w/.-]+/,0 && ws_check { print }'
例4を検出し、shebangを使用して残りの部分をトリミングせずに左のトリムラインの一部のみを印刷するには、まだやるべきことがたくさんあります。
ベストアンサー1
perl
ファイルをメモリーに入れ、ファイル内の空白ではなく、最初の文字がshebangの場合にのみ先行スペースを削除します。
perl -i.bak -0pe 's/^\s+(?=#!)//' file
または多くのファイルの場合:
for f in ./*; do perl -i.bak -0pe 's/^\s+(?=#!)//' "$f"; done
(?=#!)
これは肯定的な見通ししたがって、代替演算子はファイルの先頭にあるスペース(改行とタブを含む)のみを削除します#!
。これにより、-i.bak
状況に応じて変更されたすべてのファイルのバックアップを維持できます。期待どおりに機能すると確信している場合は yes ですrm *.bak
。
ここで使用されるオプションはperl
次のとおりです。
-0
:入力レコード区切り文字($/
)を8進数または16進数で指定します。-0
単独で使用すると、perl
ファイルは単純化され、デフォルトで1行として扱われます。 *-i.bak
:nplaceファイルを編集i
し、拡張子.bak
。-p
:入力ファイルを1行ずつ処理し、与えられたスクリプトを適用して各行を印刷します-e
。-e
:実行するスクリプトをコマンドライン引数として渡します。