Linux

如何排除以點“。”開頭的複製文件在 Linux 中?

  • December 30, 2021

我在 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

您可以匹配以您的條件開頭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

您的程式碼的主要問題不是在[[ ... ]]. 事實上,您輸入的字元串$file是一個路徑名,它的開頭包含一個目錄路徑,即只有當目錄路徑以點開頭時,模式.*才會匹配它。$dir

您似乎也使用/bin/sh而不是使用執行腳本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

引用自:https://unix.stackexchange.com/questions/630955