最終スクリプト

最終スクリプト

ファイルでいっぱいのディレクトリがあります。私の目標は、ファイルの先頭にテキストを追加することです。各ファイルの先頭にあるテキストは同じです。これは私の試みです。

#!/bin/bash                                                                                                                                                    

for file in `find . -type f -executable`;do                                                                                                                                 
    sed '/\#!/bin/bash\/a Hello Word'                                                                                                                                            


done

私のスクリプトは競合のみが発生します。

ベストアンサー1

#!/bin/bash

for file in `find . -type f -executable`;do
    sed '/\#!/bin/bash\/a Hello Word'
fi

done

このスクリプトには多くの問題があります。


まず、fiそのif


スタイル上(fi行を削除した後)の前の空白行を削除し、doneその前にスペースを追加しますdo。しかし、これは比較的些細なことです。


ベストプラクティスによれば、推奨される最新形式の代わりにバックティックを使用してコマンドを置き換えます$(...)。バックティックのサポートは、純粋に歴史的な理由で推奨されません。


出力を繰り返すため、堅牢性の問題がありますfind。これは非常に悪い考えであり、完全に不要です。スペースまたは特殊文字を含むファイル名でスクリプトが中断されます。望むより:


スクリプトを移植可能にするには、可能であればPOSIXで指定された機能に固執する必要があります。特に-executable最も重要なfindことPOSIX が指定されていません。。代わりに試してみてください-perm +700

さらに、移植性領域では、次の順序でaSed \<newline>()を使用するGNU Sedの「追加」コマンドは機能しますが、標準ではありません。


fileループ内の変数を各ファイルの名前に順番に設定します(forファイル名に特殊文字やスペースが含まれていないと仮定すると、変数にfile次のものが含まれます)。いいえファイル名)、しかし実際には使用変数file

Sedコマンドは実行するファイルを提供しないため、標準入力から実行しようとします。したがって、スクリプトを実行すると入力を待ちます。


Sedスクリプト自体が正しくなく、機能するファイル名がないという事実とは無関係です。

/正規表現(最も一般的なもの)で区切り文字として使用する場合は、正規表現/でその文字が出てくるすべての項目をバックスラッシュでエスケープする必要があります。コマンドの唯一の部分は正規表現として読み取られ、/\#!/残りの部分(これで始まる部分bin)はSedコマンドとして解釈されます。

代わりに、一般的な解決策はそれぞれを交換することです。/ その他最終正規表現の区切り記号より\/(エスケープされたようです。ただ最後のスラッシュはいいえ脱出しました。 )

一つあるSedのよく知られていない機能ここでこれを利用することができます。 どのバックスラッシュや改行以外の文字は、スラッシュだけでなく正規表現の区切り文字としても使用できます。したがって、これを/#!\/bin\/bash/Sedアドレスとして使用する代わりに、同等のアドレスを使用できます。\:#!/bin/bash:


さて、上記のすべてを処理したら、うまくいくスクリプトがありました。おそらくあなたが望むようにならないでしょう。考えるそうする必要がありますが、実際にはそうなります。何かをしなさい。これらのスクリプトは次のとおりです。

#!/bin/bash

find . -type f -perm -700 -exec sed '\:#!/bin/bash:a\
Hello World' {} +

このスクリプトは何をしますか?現在のディレクトリで実行可能ビット(所有者)が設定されているすべてのファイルを繰り返し検索し、これらのファイルごとにファイル全体を印刷し、Hello Worldtextを含む行の後にテキストを追加します#!/bin/bash

sedは実際にはありませんデザイン済みファイルをその場で編集するために使用されます。ストリームエディタです。 GNU Sedではスイッチを使ってファイルを編集できますが、-i私は次のようにします。標準ツールexファイルの編集に使用されます。


しかし、ここには別のものがあります。 Bashスクリプトにその行を追加したい場合は、有効なコマンド名ではないため、Hello World実際には何もしません。Helloおそらくあなたが望むもの印刷Bashスクリプトに「Hello World」というテキストを追加するのはecho "Hello World合理的かもしれません。

今、私たちはあなたのスクリプトが何であるかをより正確に説明したいと思います。しなければならないします。


最終スクリプト

したがって、このスクリプトの仕様のより正確な説明は次のとおりです。

  • このスクリプトは、所有者に対して実行可能ビットが設定されている現在のディレクトリ(または再帰的にすべてのサブディレクトリ)ですべての一般ファイルを見つける必要があります。
  • これらのファイルごとに、スクリプトはファイルの最初の行が文字列とまったく同じであることを確認する必要があります#!/bin/bash
  • 正確な最初の行を持つファイルの場合にのみ、スクリプトはファイルecho "Hello World"の最初の行の後に正しいテキストを挿入し、その後に改行文字を挿入する必要があります。 (この変更は標準出力として印刷するのではなくファイルに保存する必要があります。)

以下は、POSIXツールと機能のみを使用して正確な仕様に準拠したスクリプトです。

#!/bin/sh

find . -type f -perm -700 -exec sh -c '
  for f
  do
    head -n 1 "$f" | grep -qFx "#!/bin/bash" &&
      printf "%s\n" "1a" "echo \"Hello World\"" . x | ex "$f"
  done
' find-sh {} +

おすすめ記事