最も効率的な方法で、何百ものファイルの最初の行を再帰的に変更したいと思います。私がしたかった作業の例#!/bin/bash
はに変更することでした#!/bin/sh
ので、次のコマンドを思い出しました。
find ./* -type f -exec sed -i '1s/^#!\/bin\/bash/#!\/bin\/sh/' {} \;
しかし、私が理解したのは、このsedを実行するにはファイル全体を読み、元のファイルを置き換える必要があります。これを行うより効率的な方法はありますか?
ベストアンサー1
はい、sed -i
ファイル全体を読み書きしますが、行の長さが変わるため、他のすべての行の位置も移動するため、必ず必要です。
...しかし、この場合、ワイヤの長さを実際に変更する必要はありません。#!/bin/sh␣␣
ハッシュバン行を2つの末尾のスペースに置き換えることができます。オペレーティングシステムは、hashbang行を解析するときにこれらの内容を削除します。 (または2つの改行または改行+ポンド記号を使用してください。どちらもシェルが最終的に無視する追加の行を生成します。)
私たちがしなければならないのは、ファイルを開いてファイルを切り取るのではなく、最初から書き込むことだけです。通常のリダイレクトではこれを行いませ>
ん>>
が、Bashでは読み書きリダイレクトが<>
機能しているようです。
echo '#!/bin/sh ' 1<> foo.sh
またはdd
、以下を使用してください(標準POSIXオプションでなければなりません)。
echo '#!/bin/sh ' | dd of=foo.sh conv=notrunc
厳密に言えば、これらの両方は行末の改行文字を書き換えますが、問題ではありません。
もちろん、上記は与えられたファイルの先頭を無条件に上書きします。元のファイルに正しいハッシュバンがあることを確認するものを追加することは練習のままです...とにかく、本番ではこれを行いません。明らかに行を次に変更する必要がある場合もっと長く一つ。