Linuxでドット「.」で始まるファイルをコピーから除外する方法は?

Linuxでドット「.」で始まるファイルをコピーから除外する方法は?

私はあるディレクトリから別のディレクトリにファイルをコピーするためにSOのいくつかのスレッドに従いました。私は私の目的のためにinotifywaitを使用しており、1つのシナリオを除くすべてのシナリオで完全に動作します。また、不要な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

関連情報