Проверка, существует ли файл в нескольких каталогах

Походит на то, что Вы хотите сделать:

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 мешает открытой таблице файлов заполняться.

4
18.11.2018, 16:13
7 ответов

Вы не упоминаете, необходимо ли сохранить файлы (возможно, удаляющий дубликаты?), hardlink их или что-либо еще.

Так, в зависимости от Вашего намерения лучшее решение состояло бы в том, чтобы использовать одну программу как rdfind (не интерактивный), fdupes (более интерактивный, позволяя Вам выбрать который файлы сохранить или не), вареный пудинг (чтобы только сообщить о файлах, которые были дубликатом), или многие другие.

Если Вы хотите что-то более необычное с GUI, который позволит Вам выбрать, что сохранить через интерфейс "укажи и выбери", то fslint (через fslint-gui команда), был бы мой рекомендуемый выбор.

Все вышеупомянутое доступно в репозитории Debian и переходом, я думаю, что они находятся в репозиториях Ubuntu или Linux Mint, если это - то, что Вы используете.

7
27.01.2020, 20:47
  • 1
    Цель состоит в том, чтобы найти файлы, которые я загрузил, но еще не скопировал в свой каталог медиа. Хотя нахождение дубликатов будет хорошим способом очистить мой набор, не, что я надеюсь делать в этом сценарии. –  andrew.vh 13.11.2012, 21:40
  • 2
    @andrew.vh, любая из утилит выше поймала бы файлы с теми же именами, как они, в более общем плане, будут искать содержание файлов, не только их имена, как Вы уже заметили. –  rbrito 14.11.2012, 17:05

Это могло быть очень медленно, если Вы пересекаете /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 !'
4
27.01.2020, 20:47
  • 1
    Это 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
1
27.01.2020, 20:47
  • 1
    Насколько я понимаю, /media/ не подпапка /downloads/ –  Bernhard 13.11.2012, 09:07
  • 2
    Исходный плакат не упоминал это, но Ваш метод чрезвычайно только смотрит на имена файлов, не в содержании файла. То, которое является намерением исходного плаката, не ясно, все же. –  rbrito 13.11.2012, 18:05
  • 3
    Bernhard корректен, они не находятся в подпапке загрузок. –  andrew.vh 13.11.2012, 21:32
  • 4
    также, я не понял Вас, мог сравнить файлы на основе содержания. это было бы хорошо как иногда, я хотел бы переименовать файлы. –  andrew.vh 13.11.2012, 21:33
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
0
27.01.2020, 20:47
  • 1
    Тот единственные регистрации текущего каталога... –  vonbrand 08.04.2013, 20:02
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

Вы можете сверяться с известным значением и проверить его результаты на разрешение.

0
27.01.2020, 20:47

Это выведет список всех файлов в загрузках, которые также находятся в указанных вами подкаталогах /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). Любой другой символ, включая пробел, подходит.

1
27.01.2020, 20:47

Как насчет:

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
0
27.01.2020, 20:47

Теги

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