/path/to/job.py &
pid=$!
sleep 30
if kill -0 $pid; then kill -TERM $pid; fi
Использование bash
(, которое на самом деле не является инструментом POSIX, но поскольку вы упомянули об этом явно):
#!/bin/bash
names=( *:* )
printf '%s\n' "${names[@]##*:}" | sort | uniq -c |
while read count hash; do
if [[ $count -gt 1 ]]; then
echo 'Would delete/move these:'
printf '%s\n' *:"$hash"
fi
done
Это собирает все имена в текущем каталоге, содержащие символ :
, в массив names
. Предполагается, что шаблон *:*
соответствует только интересующим нас файлам и что никакие другие файлы не имеют таких имен.
Расширение "${names[@]##*:}"
приведет к списку только хэшей, которые мы сортируем и подсчитываем с помощью sort | uniq -c
.
Результат этого считывается в count
и hash
в цикле while read
, и если счетчик больше единицы, мы знаем, что хэш дублируется. Если хэш повторяется, шаблон *:"$hash"
будет соответствовать всем именам, имеющим этот хэш.
Если вы хотите удалить все файлы с повторяющимися хэшами, вы можете
rm -f./*:"$hash"
Если вы хотите сохранить один из файлов, то вместо этого сделайте, например
dupnames=(./*:"$hash" )
rm -f "${dupnames[@]:1}"
Это устанавливает массив dupnames
в совпадающие имена и удаляет все, кроме первого, из файловой системы.
Возможно, вы захотите запустить с некоторыми включенными выводами отладки и сначала сrm
отключенным , пока не убедитесь, что это действительно работает:
#!/bin/bash
names=( *:* )
printf '%s\n' "${names[@]##*:}" | sort | uniq -c |
while read count hash; do
if [[ $count -gt 1 ]]; then
echo 'Would delete/move these:'
dupnames=(./*:"$hash" )
echo rm -f "${dupnames[@]:1}"
fi
done
Вариант POSIX sh
вышеприведенного:
#!/bin/sh
for name in *:*; do
printf '%s\n' "${name##*:}"
done | sort | uniq -c |
while read count hash; do
if [ "$count" -gt 1 ]; then
echo 'Would delete/move these:'
set --./*:"$hash"
shift
echo rm -f "$@"
fi
done
Вариация последнего варианта, в котором sort | uniq -c
убирается с помощьюawk
:
#!/bin/sh
for name in *:*; do
printf '%s\n' "${name##*:}"
done |
awk ' { count[$0]++ }
END { for (hash in count) if (count[hash] > 1) print hash }' |
while read hash; do
echo 'Would delete/move these:'
set --./*:"$hash"
shift
echo rm -f "$@"
done
Фрагмент awk
также может заменить sort | uniq -c
в других фрагментах кода в этом ответе, но обратите внимание, что в финальном цикле теперь не нужно проверять, больше ли число единиц, и что он только считывает хеши.