Походит на то, что Вы хотите сделать:
awk '
{ filename = substr($0, 0, 10) "_file.log"; # input format same as output format
if (filename != lastfile) {
close(lastfile);
print 'finished writing to', lastfile;
}
print >> filename;
lastfile=filename;
}' file.log
close
мешает открытой таблице файлов заполняться.
Вы не упоминаете, необходимо ли сохранить файлы (возможно, удаляющий дубликаты?), hardlink их или что-либо еще.
Так, в зависимости от Вашего намерения лучшее решение состояло бы в том, чтобы использовать одну программу как rdfind (не интерактивный), fdupes (более интерактивный, позволяя Вам выбрать который файлы сохранить или не), вареный пудинг (чтобы только сообщить о файлах, которые были дубликатом), или многие другие.
Если Вы хотите что-то более необычное с GUI, который позволит Вам выбрать, что сохранить через интерфейс "укажи и выбери", то fslint (через fslint-gui
команда), был бы мой рекомендуемый выбор.
Все вышеупомянутое доступно в репозитории Debian и переходом, я думаю, что они находятся в репозиториях Ubuntu или Linux Mint, если это - то, что Вы используете.
Это могло быть очень медленно, если Вы пересекаете /downloads
или /media
для каждого имени файла. Так пересеките каждую иерархию только однажды, сохраните список имен файлов и затем обработайте списки.
Для простоты я предполагаю, что Ваши имена файлов не содержат новых строк.
find /downloads -type f | sed 's!^.*/\(.*\)$!\1/&!' |
sort -t / -k1,1 >/tmp/downloads.find
find /media/tv /media/music /media/movie -type f |
sed 's!^.*/\(.*\)$!\1/&!' |
sort -t / -k1,1 >/tmp/media.find
На данном этапе два .find
файлы содержат списки путей к файлам с названием файла, предварительно ожидаемого, отсортированного по имени файла. Присоединитесь к файлам на первом /
- разделенное поле, и очищает результат немного.
join -j 1 -t / /tmp/downloads.find /tmp/media.find |
sed -e 's![^/]*/!!' -e 's![^/]*/! has the same name as !'
join
управляйте, чтобы работал на меня: join -j 1 -t / /tmp/downloads.find /tmp/media.find | sed -e 's![^/]*/!!' -e 's!//! has the same name as /!'
(протестированный на двух компьютерах рабочий SLES 10 и 11.)
– jaume
15.11.2012, 11:56
Вот реализация в ударе с помощью расширения фигурной скобки:
the_file=foo.mp3
for file in /downloads/media/{tv,movie,music}/"$the_file"; do
if [[ -e $file ]]; then
printf '%s found in %s:\n' "$the_file" "${file%/*}"
fi
done
echo "Enter file name"
read file
flag=0
for i in 'ls'
do
if [ $i == $file ] ;then
echo "File exist"
flag=1
break;
fi
done
if [ $flag == 0 ] ;then
echo "File not exist"
fi
chk='/[m]edia'
for f in $chk/movies/file $chk/tv/file $chk/music/file
do [ -z "${f##"$chk"*}" ] ||
printf %s\\n "$f exists!"
done
Вы можете сверяться с известным значением и проверить его результаты на разрешение.
Это выведет список всех файлов в загрузках, которые также находятся в указанных вами подкаталогах /media:
find /downloads -type f | while IFS= read -r file ; do
bn=$(basename "$file")
find /media/tv /media/movie /media/music -type f -name "$bn"
done
и это просто выведет, был ли файл найден в одном из этих подкаталогов /media или нет.
find /downloads -type f | while IFS= read -r file ; do
bn=$(basename "$file")
count=$(find /media/tv /media/movie /media/music -type f -name "$bn" | wc -l)
[ "$count" -gt 0 ] && printf "found %s\n" "$f"
done
Если в /downloads много файлов, то выполнение find
по одному разу для каждого файла будет очень медленным. Это можно решить (если вы используете GNU find
), создав регулярное выражение, содержащее все имена файлов, которые вы хотите искать, и используя опции GNU find
-regex
или -iregex
.
REGEXP="^.*/\("
find /downloads -type f | while IFS= read -r file ; do
bn=$(basename "$file" | sed -e 's/\./\\./g')
REGEXP="$REGEXP\|$bn"
done
REGEXP="$REGEXP\)$"
find /media/tv /media/movie /media/music -type f -iregex "$REGEXP"
А вот еще одна версия, которая не использует встроенный в оболочку read
, поэтому должна быть намного быстрее:
REGEXP=$(find /downloads -type f | sed -e 's/^.*\/// ; s/\([]*\ .|[]\)/\\\1/g ;
s/$/\\|/' | tr -d '\n')
find /media/tv /media/movie /media/music -type f -iregex "^.*\($REGEXP\)$"
Обе эти версии regexp ограничены максимальной длиной строки команды оболочки - слишком много файлов, и они не будут работать.
ПРИМЕЧАНИЕ: как и большинство других ответов здесь, эти примеры не справляются с именами файлов, в которых есть новые строки (\n
). Любой другой символ, включая пробел, подходит.
Как насчет:
cd /sourcemp4folder
for i in *.mp4
do
a=$(find /destination/ -iname "$i" -print | wc -l)
if [[ $a > 0 ]]; then echo "Skip "
else echo "cp $i to /destination/"
fi
done