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
您可以匹配不以您的條件開頭
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
。使用
--exclude
with 時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