Shebangが可能になる前に先行スペースを削除してください。

Shebangが可能になる前に先行スペースを削除してください。

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:実行するスクリプトをコマンドライン引数として渡します。

おすすめ記事