Рекурсивно искать файлы с определенным расширением

Из точки mysql вы можете сделать

alter table YOURTABLE add unique index(pageId, name);

Если ваша формулировка верна и вы хотите сделать это с php, вы можете сделать

$already_done = array();
foreach ($records as $record)
{
   $unique_hash = md5($record['name'].$record['pageId']);
   if (!in_array($unique_hash, $already_done))
   {
      $already_done[] = $unique_hash;
      // sql insert here
   }
}

в любом случае, вы просто отлично.

375
задан fedorqui 1 May 2013 в 14:24
поделиться

10 ответов

find {directory} -type f -name '*.extension'

пример для поиска всех CSV-файлов в текущем каталоге и его подкаталогах

find . -type f -name '*.csv'
154
ответ дан Hedgehog 1 May 2013 в 14:24
поделиться

Синтаксис, который я использую, немного отличается от предложенного @Matt:

find $directory -type f -name \*.in

(это на одно нажатие клавиши меньше).

58
ответ дан Scott C Wilson 1 May 2013 в 14:24
поделиться

Без использования find:

du -a $directory | awk '{print $2}' | grep '\.in
12
ответ дан rtrn 1 May 2013 в 14:24
поделиться

Чтобы найти все файлы pom.xml в текущем каталоге и распечатать их, вы можете использовать:

find . -name 'pom.xml' -print
6
ответ дан fedorqui 1 May 2013 в 14:24
поделиться
find $directory -type f -name "*.in"

немного короче всего этого (и безопаснее - имеет дело с пробелами в именах файлов и каталогов).

Возможно, ваш скрипт не работает для записей, в имени которых нет ., что делает $extension пустым.

668
ответ дан Mat 1 May 2013 в 14:24
поделиться
  1. После browsefolders ()
  2. отсутствует {. Все $in должны быть $suffix
  3. . Строка с cut дает вам только среднюю часть front.middle.extension. Вы должны прочитать руководство по оболочке на ${varname%%pattern} и у друзей.

Я предполагаю, что вы делаете это как упражнение в написании сценариев оболочки, в противном случае уже предложенное решение find - это путь.

Для проверки правильности синтаксиса оболочки без запуска сценария используйте sh -n scriptname.

10
ответ дан Jens 1 May 2013 в 14:24
поделиться
find $directory -type f -name "*.in"|grep $substring
1
ответ дан Sobrique 1 May 2013 в 14:24
поделиться
for file in "${LOCATION_VAR}"/*.zip
do
  echo "$file"
done 
1
ответ дан rollstuhlfahrer 1 May 2013 в 14:24
поделиться
find "$PWD" -type f -name "*.in"
0
ответ дан kip2 1 May 2013 в 14:24
поделиться

Хотя здесь может быть полезна команда find, сама оболочка предоставляет опции для выполнения этого требования без каких-либо сторонних инструментов. Оболочка bash предоставляет расширенную опцию поддержки glob, с помощью которой вы можете получить имена файлов по рекурсивным путям, которые соответствуют нужным расширениям.

Расширенной опцией является extglob, которую необходимо установить с помощью опции shopt, как показано ниже. Опции включаются с поддержкой -s и отключаются с помощью флага -u. Кроме того, вы можете использовать еще несколько опций, то есть nullglob, в которых непревзойденный глобус сметается целиком, заменяется набором нулевых слов. И globstar, который позволяет проходить по всем каталогам

shopt -s extglob nullglob globstar

Теперь все, что вам нужно сделать, это сформировать выражение glob, включающее файлы определенного расширения, которые вы можете сделать, как показано ниже. Мы используем массив для заполнения результатов глоба, потому что при правильном цитировании и расширении имена файлов со специальными символами останутся нетронутыми и не сломаются из-за разбиения слов оболочкой.

Например, чтобы перечислить все файлы *.csv в рекурсивных путях

fileList=(**/*.csv)

Опция ** состоит в рекурсии через подпапки, а *.csv - расширение глобуса до включите любой файл упомянутых расширений. Теперь для печати реальных файлов просто сделайте

printf '%s\n' "${fileList[@]}"

Использование массива и правильное расширение в кавычках - правильный путь при использовании в скриптах оболочки, но для интерактивного использования вы можете просто использовать ls с выражение glob как

ls -1 -- **/*.csv

Это вполне может быть расширено для соответствия нескольким файлам, т.е. файлам, заканчивающимся множественным расширением (то есть аналогично добавлению нескольких флагов в команде find). Например, рассмотрим случай, когда нужно получить все файлы рекурсивных изображений, например, с расширениями *.gif, *.png и *.jpg, все, что вам нужно, это

ls -1 -- **/+(*.jpg|*.gif|*.png)

. Это вполне можно расширить, чтобы иметь отрицать результаты также. С тем же синтаксисом можно использовать результаты glob для исключения файлов определенного типа. Предположим, что вы хотите исключить имена файлов с расширениями, указанными выше, вы можете сделать

excludeResults=()
excludeResults=(**/!(*.jpg|*.gif|*.png))
printf '%s\n' "${excludeResults[@]}"

Конструкция !() является операцией отрицания, которая не включает в себя какие-либо расширения файлов, перечисленные внутри, и | является чередованием оператор, аналогичный тому, который используется в библиотеке расширенных регулярных выражений для сопоставления ИЛИ глобусов.

Обратите внимание, что эта расширенная поддержка glob недоступна в оболочке POSIX bourne и является чисто специфической для последних версий bash. Так что, если вы рассматриваете переносимость сценариев, работающих в оболочках POSIX и bash, эта опция будет неправильной.

4
ответ дан Inian 1 May 2013 в 14:24
поделиться
Другие вопросы по тегам:

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