Как ИСКЛЮЧИТЬ копирование файлов, начинающихся с точки "." в линуксе?

Кроме того, команду column -tможно использовать для форматирования текста в столбцах.

column -t file

Разделитель столбцов по умолчанию — " ". В примере строки имеют несколько пробелов, но только первый разделяет столбцы :, мы можем заменить первый на «:» и использовать его в качестве разделителя.

$ sed 's/ /:/1' file | column -s ':' -t
super+t            sticky toggle
super+Shift+space  floating toggle
super+Shift+r      restart
super+Shift+d      mode $mode_launcher
...
2
30.01.2021, 23:31
2 ответа

Вы можете сопоставить 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
3
18.03.2021, 22:34

Основная проблема с вашим кодом заключается не в использовании сопоставления с образцом в [[... ]]. Дело в том, что строка, которую вы получаете в $file, представляет собой путь, который содержит путь к каталогу в начале, т. е. шаблон .*будет соответствовать ему только в том случае, если путь к каталогу $dirначинается с точки.

Похоже, вы также запускаете сценарий с /bin/sh, а не с bash, так что вы не обязательно ожидаете, что какой-либо из тестов [[... ]]вообще сработает.


Чтобы исключить шаблоны имен файлов, соответствующие inotifywait, используйте --exclude 'PATTERN'. Например:

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

Шаблон, используемый здесь с --exclude, соответствует любому имени пути, которое заканчивается именем файла, начинающимся с точки. Об этом не сообщает inotifywait.

При использовании --excludeс 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
2
18.03.2021, 22:34

Теги

Похожие вопросы