Удалить самую старую папку из пути с исключением

Я предпочитаю использовать mpack для отправки вложений в формате MIME

как в:

mpack -s "message" file email@example.com

Name

mpack - pack a file in MIME format Synopsis

mpack [ -s subject ] [ -d descriptionfile ] [ -m maxsize ] [ -c content-type ] file address... mpack [ -s subject ] [ -d descriptionfile ] [ -m maxsize ] [ -c content-type ] -o outputfile file mpack [ -s subject ] [ -d descriptionfile ] [ -m maxsize ] [ -c content-type ] -n newsgroups file Description

The mpack program encodes the the named file in one or more MIME messages. The resulting messages are mailed to one or more recipients, written to a named file or set of files, or posted to a set of newsgroups.

1
30.09.2018, 08:59
5 ответов

Вы можете адаптировать исходное решение для чтения файлов до тех пор, пока оно не найдет тот, который не исключен:

while IFS= read -r -d '' line
do
    file="${line#* }"
    if [ "$file" = './my-excluded-directory' ]
    then
        continue
    fi
    [do stuff with $file]
    break
done < <(find. -maxdepth 1 -type d -printf '%T@ %p\0' | sort -z -n)

(-d ''эквивалентен оригиналу, потому что в строках не может быть символов NUL.)

readРабота с длинным списком медленная, и @mosvy прав, что вы можете выполнять фильтрацию с довольно неприятным findсинтаксисом:

IFS= read -r -d '' < <(find. -maxdepth 1 -type d \( -name 'my-excluded-directory' -prune -false \) -o -printf '%T@ %p\0' | sort -z -n)
file="${REPLY#* }"
# do something with $file here
0
28.04.2021, 23:41

Нет, это решение не идеально, потому что оно зависит от множества крайне не -переносимых функций (find -printf, sort -z, read -dи т. д. ).

Мое решение также не идеально, так как оно зависит от оператора -otиз test(, который проверяет, старше ли файл, чем другой ); однако, кажется, что он гораздо лучше поддерживается (*bsd, busybox, solaris, linux ).

# usage with_2nd_oldest 'command' files...
with_2nd_oldest(){
        cmd="$1"; shift
        oz="$1"; shift; oy=$1
        for f; do
                if [ "$f" -ot "$oz" ]; then oy=$oz oz=$f
                elif [ "$f" -ot "$oy" -a "$f" != "$oz" ]; then oy=$f
                fi
        done
        $cmd "$oy"
}
$ with_2nd_oldest 'echo rm -fr --' dir/*/

Это также может обрабатывать повторяющиеся аргументы:

$ for i in `seq 1 9`; do mkdir -p $i; sleep 1; done
$ with_2nd_oldest echo 7 7 1 1 3 3 2 2 8 9 5 1
2

Для другого более старого вопроса, где требовался самый старый файл/каталог, это еще проще:

with_oldest(){
        cmd="$1"; shift
        oz="$1"; shift
        for f; do test "$f" -ot "$oz" && oz=$f; done
        $cmd "$oz"
}

Оба могут быть тривиально адаптированы для пропуска произвольных путей или для чтения списка файлов из стандартного ввода.

0
28.04.2021, 23:41

Сzsh:

set -o extendedglob # best in ~/.zshrc
rm -rf -- ^that-folder-to-keep(D/Om[1])

С решением, предоставленным в этом другом вопросе и ответе:

IFS= read -r -d '' line < <(
  find. -maxdepth 1 \
    ! -name that-folder-to-keep \
    -type d -printf '%T@ %p\0' 2>/dev/null | sort -z -n) &&
  rm -rf "${line#* }"

Если вы хотите удалить второй по старшинству:

zsh:

rm -rf -- *(D/Om[2])

Утилиты GNU:

{ IFS= read -r -d '' line &&
  IFS= read -r -d '' line &&; } < <(
  find. -maxdepth 1 \
    -type d -printf '%T@ %p\0' 2>/dev/null | sort -z -n) &&
  rm -rf "${line#* }"
0
28.04.2021, 23:41
#!/bin/bash
while IFS= read -r -d '' line
do
    file="${line#* }"
    if [ "$file" = './Development_Instance' ]
    then
        continue
fi

if [ "$file" = './lost+found' ]
then
continue
fi
    echo $file
    break
done < <(find. -maxdepth 1 -type d -printf '%T@ %p\0' | sort -z -n)

Вот как я справился. Я знаю, что это не самый элегантный способ сделать это. Это просто делает вещь для меня.

0
28.04.2021, 23:41

Одним из «хитрых» способов сделать это было бы изменение временной метки исключенного каталога в начале и восстановление его временной метки в конце:

$ cd "$(mktemp --directory)"
$ echo foo > example.txt
$ modified="$(date --reference=example.txt +%s)" # Get its original modification time
$ touch example.txt # Set the modification time to now
[delete the oldest file]
$ touch --date="@$modified" example.txt # Restore; the "@" denotes a timestamp

Применяются обычные предостережения:

  • Это не позволит восстановить исходную метку времени, если будет уничтожено до завершения (или в случае потери питания и т. д. ). Если действительно важно восстановить метку времени, вы можете использовать touch --reference="$path" "${path}.timestamp", чтобы сохранить метку времени в реальном файле и восстановить с помощью touch --reference="${path}.timestamp" "$path".
  • Имена параметров основаны на основных инструментах GNU. Возможно, вам придется использовать менее читаемые имена параметров, чтобы сделать то же самое на других *nix.
0
28.04.2021, 23:41

Теги

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