0

問題:
filenames.txt というファイル名のリストがあります。

/usr/share/important-library.c
/usr/share/youneedthis-header.h 
/lib/delete/this-at-your-peril.c

これらのファイルの名前を変更または削除する必要があり、プロジェクト ディレクトリ ツリーでこれらのファイルへの参照を見つける必要があります。これらのファイルを/home/noob/my-project/削除または修正できるようにするためです。

私の考えでは、 bash を使用して filename: を抽出basename filenameし、 for ループを使用してプロジェクト ディレクトリで grep します。

FILELISTING=listing.txt
PROJECTDIR=/home/noob/my-project/

for f in $(cat "$FILELISTING"); do
    extension=$(basename ${f##*.})
    filename=$(basename ${f%.*})
    pattern="$filename"\\."$extension"
    grep -r "$pattern" "$PROJECTDIR"
done

私はこのプロジェクトを完全に台無しにすることができました-誰かが私の論理に欠陥があると思いますか? より良い: 巨大なディレクトリ ツリーでこれを行うための、より信頼性が高くスケーラブルな方法を見つけますか? リビジョン管理が検討されていないと仮定しましょう (実際にはそうです)。

4

2 に答える 2

5

いくつかのコメント:

  • それ以外の

    for f in $(cat "$FILELISTING") ; do
        ...
    done
    

    と書く方がいくらか安全です

    while IFS= read -r f ; do
        ...
    done < "$FILELISTING"
    

    そうすれば、ファイル名にスペース、タブ、アスタリスクなどがあっても、コードで問題が発生することはありません (ただし、改行はサポートされません)。

  • とに分離fextensionfilenameそれらを で再構築するというあなたの目標は\.、ファイル名をリテラル文字列として扱うことです。右?同様に、を「1つのドット」ではなく「任意の文字」を意味するものとしてgrep扱うのではないかと心配しています. .より一般的な解決策は、パターンを正規表現ではなく固定文字列として扱うように指示するgrep'sオプションを使用することです。-F

    grep -r -F "$f" "$PROJECTDIR"
    
  • あなたの紹介では の使用について言及してbasenameいますが、実際には使用していません。それは意図的なものですか?

  • あなたの不使用basenameが意図的である場合、filenames.txt実際には検索するパターンのリストが含まれています。この場合、grep-fオプションは、ファイルから改行で区切られたパターンのリストを取得するように指示するため、ループを記述する必要さえありません。

    grep -r -F -f "$FILELISTING" "$PROJECTDIR"
    

  • のようなものを使用して、プロジェクトをバックアップする必要がありますtar -czf backup.tar.gz "$PROJECTDIR"。「リビジョン管理が検討されていない」からといって、ロールバック戦略が使えないわけではありません!

追加するために編集:

  • すべてのベース名をgrep一度に渡すには、呼び出しが別々であるかのようにそれらをループするよりもスマートに処理できることを期待して、次のように記述できます。

    grep -r -F "$(sed 's#.*/##g' "$FILELISTING")" "$PROJECTDIR"
    

    (簡潔にするために+sedではなくを使用しましたが、必要に応じて 内でループ全体を使用できます。)whilebasename"$(...)"

于 2013-05-24T20:18:32.980 に答える
1

これは IDE の仕事です。

これが危険な作業であることは間違いありません。ビルド プロセス、検索ディレクトリ、およびディレクトリの順序を理解していない限り、どのヘッダーがどのファイルに含まれているかを判断することはできません。

次のような単純なものを見てみましょう。

# include "sql.h"

プロジェクトにファイルがありますheaders/sql.h。そのファイルは必要ですか?多分そうです。そうでないかもしれない。もあり/usr/include/sql.hます。実際に使われているのはこれかもしれません。インクルードディレクトリMakefileの順序を見て、どれがどれであるかを確認しないとわかりません。

次に、含まれるライブラリがあり、コンパイルできるようにするために独自のヘッダー ファイルが必要になる場合があります。そして、C プリプロセッサに到達すると、本当に苦労することになります。

これは、IDE (統合開発環境) のタスクです。IDE はプロジェクトをビルドし、ファイルやその他のリソースの依存関係を追跡します。Java の世界では、ほとんどの人が Eclipse を使用しており、そうした開発者向けの C/C++ プラグインがあります。ただし、ウィキペディアには 20 を超えるものがリストされており、それらのほとんどすべてがオープン ソースです。最適なものは環境によって異なります。

于 2013-05-24T20:54:25.707 に答える