如何排除复制以点“.”开头的文件在 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

您可以匹配RegExfor 文件不是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=读取-r行”)。

有了/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

相关内容