실제 소스 파일만 찾도록 찾기 출력을 필터링하시겠습니까?

실제 소스 파일만 찾도록 찾기 출력을 필터링하시겠습니까?

소스 파일(*.c)을 포함하는 대규모 디렉토리 트리가 있는데, 그 중 일부(전부는 아님)는 실제로 다음을 생성하는 전처리에 의해 생성됩니다.어느.c에서어느.qc 파일.

종종 이러한 파일을 사용하여 작업을 수행해야 하지만 최종 소스 파일만 사용해야 하는 경우가 있습니다.어느.qc, 말도 안 돼요.어느.c(그러나 그렇지 않은 경우저게 뭐에요.qc 그렇다면 정말 살펴봐야 할 것 같아요저게 뭐에요. 씨).

다음과 같이 시작하십시오.

find data-utils -name '*.qc' -o -name '*.c' | xargs grep SMS_GEN

find 출력의 일부가 다음과 같다고 가정합니다.

data-utils/whatever.c
data-utils/whatsit.c
data-utils/whatever.qc

통과하지 못하도록 찾기 결과를 필터링하는 데 사용할 수 있는 기존 도구가 있습니까?어느.c를 xargs로(또는 조회 이후의 모든 것). 즉, 위의 필터 결과는 다음과 같아야 합니다.

data-utils/whatsit.c
data-utils/whatever.qc

아니면 처음부터 뭔가를 작성해야 합니까?

답변1

파일 이름 접미사가 있는 파일을 찾습니다. 그러나 그러한 파일이 존재하는 경우 .c해당 파일의 경로 이름을 반환합니다..qc

find server/data-utils -type f -name '*.c' -exec sh -c '
    for pathname do
        if [ -f "${pathname%.c}.qc" ]; then
            printf "%s\n" "${pathname%.c}.qc"
        else
            printf "%s\n" "$pathname"
        fi
    done' sh {} +

server/data-utils검색 경로 안 이나 아래에서 이름을 찾습니다 .c. 이러한 경로 이름의 일괄 처리에 대해 짧은 쉘 스크립트가 호출됩니다. 쉘 스크립트는 주어진 각 경로 이름을 테스트하고 .c이를 로 바꾸고 .qc, 수정된 경로 이름이 기존 일반 파일(또는 해당 파일에 대한 심볼릭 링크)을 참조하는 경우 이를 인쇄합니다. 그렇지 않으면 원래 경로 이름이 인쇄됩니다.

관련된:


위의 변형일 뿐입니다.건조 원리애플리케이션:

find server/data-utils -type f -name '*.c' -exec sh -c '
    for pathname do
        qc_pathname=${pathname%.c}.qc

        if [ -f "$qc_pathname" ]; then
            out=$qc_pathname
        else
            out=$pathname
        fi

        printf "%s\n" "$out"
    done' sh {} +

...아니면 그냥

find server/data-utils -type f -name '*.c' -exec sh -c '
    for pathname do
        qc_pathname=${pathname%.c}.qc
        [ -f "$qc_pathname" ] && pathname=$qc_pathname
        printf "%s\n" "$pathname"
    done' sh {} +

답변2

나는 작업을 수행하기 위해 awk 스크립트를 생각해 냈습니다. O(n^2)로 특별히 효율적이지는 않지만 행을 재정렬(필터링되지 않음)하지 않는다는 장점이 있습니다.

function supercedes ( a, b ) {
        suffixa=match(a, /\.[^/.]*$/);
        suffixb=match(b, /\.[^/.]*$/);
        if ((suffixa == 0) || (suffixa != suffixb)) return 0;
        if (substr(a,1,suffixa) != substr(b,1,suffixb)) return 0;
        return (substr(a,suffixa) == A) && (substr(b,suffixb) == B);
}
BEGIN { n = 0; }
{ item[n++] = $0; }
END {
        for (i = 0; i < n; ++i) {
                show = 1;
                for (j = 0; j < n; ++j) {
                        if (j != i) {
                                if (supercedes(item[i], item[j])) {
                                        show = 0;
                                        break;
                                }
                        }
                }
                if (show) print item[i];
        }
}

사용 예:

find server/data-utils -name '*.qc' -o -name '*.c' | \
    awk -f filter.awk -vA=.c -vB=.qc

관련 정보