Как получить полный список подкаталогов (включая подкаталоги подкаталогов)?

У меня есть тысячи папок городов (например, city1, city2 и т. д., но на самом деле они называются NewYork, Boston и т. д.). Каждая папка также содержит две подпапки: land и house.

Таким образом, структура каталогов выглядит так:

current dictionary
  ---- city1
     ----- house 
         ------ many .xlsx files
     ----- land
  ----- city2
  ----- city3
  ···
  ----- city1000

Я хочу получить полный список всех подкаталогов и выполнить некоторые манипуляции (например, import excel). Я знаю, что есть расширенная функция макроса: local list: dir для решения этой проблемы, но кажется, что она может возвращать только first tier подкаталогов, например city_i, а не более глубокие.

В частности, если я хочу действовать во всех домашних папках, какой рабочий процесс мне нужен?

Я сделал первоначальную попытку написать код для достижения своей цели:

cd G:\Data_backup\Soufang_data
local folder: dir . dirs "*"
foreach i of local folder {
     local `i'_house : dir  "G:\Data_backup\Soufang_data\``i''\house" files "*.xlsx"

     local count = 1
     foreach j of local `i'_house {
        cap import excel "`j'",clear
        cap sxpose,clear
        cap drop in 1/1

        if `count'==1 {
          save `i'.dta, replace
            }
        else          {
         cap qui append using `i'
         save `i'.dta,replace
            }

       local ++count
     }
}

Что-то не так с:

``i'' 

в каталоге я все равно безуспешно пытался заставить его работать.

У меня есть другой пост в этом проекте.


Дополнительные примечания:

Как указывает Ник, проблемы вызывает обратная косая черта. Однако, двигаясь с этой точки, я сталкиваюсь с другой проблемой. Скажем, без сложных действий, я просто хочу проверить, работают ли мои циклы, поэтому я пишу следующий фрагмент кода:

set more off
cd G:\Data_backup\Soufang_data
local folder: dir . dirs "*"
foreach i of local folder {
     di "`i'"
     local `i'_house : dir  "G:\Data_backup\Soufang_data/`i'\house" files "*.xlsx"

     foreach j of local `i'_house {
        di "`j'"
     }
}

Однако результат на экране выглядит примерно так:

city1
project100
project99
······
project1

Похоже, что код зацикливается только на один цикл по первому городу, но не достигает city2, city3 и так далее. Я подозреваю, что это из-за моего проблематичного написания местного, особенно в этой строке, но я не уверен:

foreach j of local `i'_house

person zlqs1985    schedule 22.02.2016    source источник
comment
Обратная косая черта не смешивается с локальными макросами. Много задокументировано, например. stata.com/manuals14/u.pdf 18.3.11 stata-journal.com/sjpdf.html?articlenum=pr0042   -  person Nick Cox    schedule 22.02.2016
comment
@NickCox, спасибо, Ник, проблема действительно в обратной косой черте. Двигаясь с этого момента, я сталкиваюсь с новой проблемой, пожалуйста, дайте мне новое вдохновение.   -  person zlqs1985    schedule 23.02.2016
comment
Если элементы в folder содержат встроенные пробелы, они не подходят для использования в качестве имен макросов.   -  person Nick Cox    schedule 23.02.2016


Ответы (2)


Хотя это и не решение проблемы, которую вы на самом деле представляете, более простым способом может быть использование filelist из SSC (ssc install filelist).

Примером может быть:

. // list all files
. filelist, directory("D:\Datos\RFERRER\Desktop\example")
Number of files found = 5

. 
. // strange way of tagging directories ending in "\house"
. // change at will
. gen tag = substr(reverse(dirname),1,6) == "esuoh/"

. 
. order tag

. list

     +----------------------------------------------------------------------------------------------+
     | tag   dirname                                                     filename             fsize |
     |----------------------------------------------------------------------------------------------|
  1. |   0   D:\Datos\RFERRER\Desktop\example/proj_1                     newfile.txt              0 |
  2. |   1   D:\Datos\RFERRER\Desktop\example/proj_2/house               somefile.txt             0 |
  3. |   0   D:\Datos\RFERRER\Desktop\example/proj_3/subproj_3_2         newfile2.txt             0 |
  4. |   1   D:\Datos\RFERRER\Desktop\example/proj_3/subproj_3_2/house   anothernewfile.txt       0 |
  5. |   1   D:\Datos\RFERRER\Desktop\example/proj_3/subproj_3_2/house   someotherfile.txt        0 |
     +----------------------------------------------------------------------------------------------+

После этого используйте keep или drop в зависимости от переменной tag.

Графически каталог выглядит так:

введите здесь описание изображения

(Я использую Stata 13. Проверьте help string functions, чтобы узнать о других способах пометки.)

person Roberto Ferrer    schedule 22.02.2016
comment
спасибо, рад слышать, что такая полезная команда существует. Однако это не совсем подходит для моей конкретной цели, так как я хочу извлечь файлы из некоторых подпапок, а не из всех. В filelist , насколько я вижу из файла справки, можно выбрать только шаблон файла, а не каталога. - person zlqs1985; 23.02.2016
comment
filelist создает набор данных с информацией о том, что было найдено. Чтобы продолжить, вам нужно только отбросить то, что вы считаете неактуальным. - person Roberto Ferrer; 23.02.2016
comment
спасибо, Роберто, после некоторой борьбы (действительно умный) подход работает. Однако мне интересно, когда у меня есть сотни тысяч файлов (даже больше), может ли valuesof хранить такое большое количество значений? я использую стату14 - person zlqs1985; 29.02.2016
comment
См. help limits, чтобы узнать количество символов в макросе и возможности расширения. Не зная заранее приблизительное количество символов, которое мне нужно сохранить, я бы постарался избежать использования макроса. - person Roberto Ferrer; 29.02.2016

Ваша исправленная проблема может привести к

local folder: dir . dirs "*"
foreach i of local folder {
     di "`i'"
     local house : dir  "G:\Data_backup\Soufang_data/`i'\house" files "*.xlsx"

     foreach j of local house {
        di "`j'"
     }
}

но ясно, что мы не можем видеть вашу файловую структуру или имена файлов.

person Nick Cox    schedule 23.02.2016