Linux에서 점 "."으로 시작하는 파일을 복사에서 제외하는 방법은 무엇입니까?

Linux에서 점 "."으로 시작하는 파일을 복사에서 제외하는 방법은 무엇입니까?

나는 한 디렉토리에서 다른 디렉토리로 파일을 복사하기 위해 SO의 여러 스레드를 따라갔습니다. 나는 내 목적을 위해 inotifywait를 사용하고 있으며 하나의 시나리오를 제외한 모든 시나리오에서 완벽하게 작동합니다. 또한 나는 원하지 않는 DOT 접두사(예: .tmp.swp)로 시작하는 파일을 복사합니다.

이것을 시도했지만 -json접미사가 붙은 파일도 복사되지 않았습니다. 나는 .tmp.abcd-json복사되고 싶지 않습니다 . &&다음을 포함한 모든 항목을 복사한 후 수표를 제거 하면 .tmp.abcd-json:

다음은 디렉토리의 일부 내용입니다. 이는 .tmp필수는 아니지만 항상 로 시작한다고 보장되는 것은 아닙니다 . 무시해야 하는 접두사로 무작위로 시작하는 .tmp다른 파일도 본 적이 있습니다 ..

abcd-json .tmp.abcd-json

#!/bin/sh
dir=/var/lib/docker/containers
target=/var/log/splunkf
inotifywait -m -r "$dir" --format '%w%f' -e create -e modify  \
| while read file;
        do
                if [[ $file == "-json"* ]] && [[ $file != "."* ]];
                then
                    echo Copying  $file to $target
                    cp -- "$file" "$target";
                else
                    echo NOT Copying  $file to $target
                fi
        done

답변1

RegEx파일을 일치시킬 수 있습니다아니요dot귀하의 상황부터 시작하여 if:

while read file;
        do
          f="$(basename -- $file)"
          if ! [[ "$f" =~ ^\. ]];
          then
             echo Copying  $file to $target
             cp -- "$file" "$target";
          else
             echo NOT Copying  $file to $target
          fi

답변2

코드의 주요 문제는 에 없습니다 [[ ... ]]. 실제로 얻은 문자열은 시작 부분에 디렉터리 경로가 포함된 경로 이름입니다. 즉, 패턴은 $file점으로 시작하는 경우 .*에만 디렉터리 경로와 일치합니다 .$dir

/bin/sh또한 with 대신을 사용하여 스크립트를 실행하는 것으로 나타나 므로 테스트가 bash반드시 작동할 것이라고 기대할 수는 없습니다 .[[ ... ]]


일치하는 파일 이름 패턴을 제외하려면 다음을 inotifywait사용하십시오 --exclude 'PATTERN'.

inotifywait -m -r --format '%w%f' -e create -e modify \
        --exclude '/\.[^/]*$' "$dir"

여기에 사용된 패턴은 --exclude점으로 시작하는 파일 이름으로 끝나는 모든 경로 이름과 일치합니다. 이러한 내용은 보고되지 않습니다 inotifywait.

--excludewith 를 사용하면 inotifywait코드가 다음으로 축소됩니다.

#!/bin/sh

dir=/var/lib/docker/containers
target=/var/log/splunkf

inotifywait -m -r --format '%w%f' -e create -e modify \
        --exclude '/\.[^/]*$' "$dir" |
xargs -I {} cp -- {} "$target"

이것은 분명히 파일 이름에 개행 문자가 포함되어 있지 않다고 가정합니다.


bash명시적인 테스트 및 진단 출력이 있는 루프를 사용하려면 다음을 사용할 수 있습니다.

#!/bin/bash

dir=/var/lib/docker/containers
target=/var/log/splunkf

inotifywait -m -r --format '%w%f' -e create -e modify "$dir" |
while IFS= read -r pathname; do
    if [[ ${pathname##*/} == .* ]]; then
        printf 'Not copying "%s"\n' "$pathname" >&2
    else
        printf 'Copying "%s" to "%s"\n' "$pathname" "$target" >&2
        cp -- "$pathname" "$target"
    fi
done

IFS= read -r이는 파일 이름에서 주변 공백이 제거되는 것을 방지하고 백슬래시 시퀀스를 해석하는 것을 방지하기 위한 것입니다(참조) ."IFS=read-r-line" 이해).

그것으로 /bin/sh당신은 할 것입니다

#!/bin/sh

dir=/var/lib/docker/containers
target=/var/log/splunkf

inotifywait -m -r --format '%w%f' -e create -e modify "$dir" |
while IFS= read -r pathname; do
    case ${pathname##*/} in
        .*)
            printf 'Not copying "%s"\n' "$pathname" >&2
            ;;
        *)
            printf 'Copying "%s" to "%s"\n' "$pathname" "$target" >&2
            cp -- "$pathname" "$target"
    esac
done

관련 정보