findを使用してディレクトリに含まれるすべてのファイルに対してプログラムを再帰的に実行する方法

findを使用してディレクトリに含まれるすべてのファイルに対してプログラムを再帰的に実行する方法

ディレクトリに含まれるすべてのファイルに対して実行したい実行可能ファイルを作成しました。

プログラムは次のとおりです。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/xattr.h>
#include <string.h>
#include <errno.h>


int main(int argc, char const *argv[]){
    char argNormaux[4096] = {0};
    char argNeg[4096] = {0};
    char argEt[4096] = {0};
    int nbArgsNormaux = 0;
    if (argc > 2){
        for (int i = 2; i < argc; i++){
            const char *arg = argv[i];
            if (strstr(argv[i],"et") != NULL){
                strcat(argEt, argv[i]);
            }
            else if (strstr(argv[i], "!") != NULL){
                strcat(argNeg, argv[i]);
            }
            else {
                strcat(argNormaux, argv[i]);
                nbArgsNormaux++;
            }
        }
        const char *path = argv[1];
        char buf[4096];
        int rc;
        rc = listxattr(path, buf, sizeof(buf));
        if (rc < 0){
            perror("listxattr");
        }
        else {
            if (strlen(buf) == 0){
                printf("No tag.\n");
                return 1;
            }
            int tagsNormauxCheck = 0;
            int tagsNegCheck = 0;
            char *token = buf;
            while(*token){
                char tagBuf[4096];
                if (strlen(token) == 2){
                    if (strcmp(token, "\0\0\0")) break;
                }
                rc = getxattr(path, token, &tagBuf, sizeof(tagBuf));
                if (rc < 0){
                    perror("getxattr");
                }
                else {
                    if (strstr(argNormaux, tagBuf) != NULL) {
                        tagsNormauxCheck++;
                    }
                    if (strstr(argNeg, tagBuf) != NULL) {
                        tagsNegCheck = 1;
                        break;
                    }
                }
                memset(&tagBuf, 0, sizeof(tagBuf));
                token = strchr(token, '\0');
                token++;
            }
            if (tagsNormauxCheck == nbArgsNormaux && tagsNegCheck == 0){
                printf("Le fichier %s possède la combinaison des tags donnés.", path);
            }
        }
    }
    else {
        printf("Pas assez d'arguments.");
    }
    return 0;
}

これは私が使用したいコマンドラインです:

find . -type f -exec ./logic testDir/ essai '{}' \;

私が期待したのは、logic実行可能ファイルをディレクトリ内のすべてのファイルに適用することでしたが、testDirそれが行うことはtestDirディレクトリ内のすべてのファイルに直接適用することでした。これは私が望むものではありませんlogic 。それで、私が望むことを達成するために何をすべきかわかりません。適用されたファイルパラメータはlogicこのコマンドでは変更されません。

編集:達成したい目標、目的、logicおよび仕組みに関する詳細な背景情報を追加します。

logicファイルにに渡された拡張引数の組み合わせがあるかどうかを示すプログラムですlogic。スタンドアロン実装の例logicは次のとおりですlogic testfile.txt programming class university \!art。基本的にtestfile.txtラベルの組み合わせがあるかどうかを教えてくださいprogramming and class and university and not art

それでは、次のようなディレクトリがあるとしましょう。

testDir/
├── dir2
│   ├── dir2file1.txt
│   ├── dir2file2.txt
│   └── dir2file3.txt
├── file1.txt
├── file2.txt
├── file3.txt
└── file4.txt

1 directory, 7 files

logicこのディレクトリツリーのすべてのファイルに対して実行したいと思います。 (フォルダを除く)

したがって、基本的に私の問題は、logic渡されたファイルパラメータがfind使用中に変更されないことです。ここに滞在しますが、到着するまでそのまま残ることを願っtestDir/ています。testDir/file1.txttestDir/file2dir2file3.txt

とにかく動作させる方法はありますか?

ありがとうございます。

答え1

ファイルパスが欲しいようです。最初プログラムパラメータ:

find testDir -type f -exec ./logic {} essai \;

これはディレクトリtestDir(およびのすべてのサブディレクトリtestDir)から通常のファイルを検索し、見つかった各ファイルのファイルパスessai名を最初の引数(および2番目の引数)としてプログラムを呼び出します。

このコマンドとユーザーコマンドの違いは次のとおりです。

find . -type f -exec ./logic testDir/ essai '{}' \;

それだけです。

  1. 次のように見つかったファイルのパス名最後コマンドラインパラメータ、
  2. 最初のパラメータtestdir/は常に
  3. 検索した内容現在のディレクトリ(およびそのサブディレクトリ)。

答え2

これがあなたが探していることです -

find testDir/ -type f | awk '{system("./logic "$1" -your_args_here")}'

関連情報