TCL: Рекурсивно ищите подкаталоги для определения источника всех .tcl файлов

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

SQL для создания и заполнения таблиц:

IF OBJECT_ID('tempdb..#tmpTable1') IS NOT NULL
  /*Then it exists*/
  DROP TABLE #tmpTable1

CREATE TABLE #tmpTable1 (
    code varchar(4) not null,
    ItemNo smallint not null )

insert into #tmpTable1 VALUES('A', 12345)
insert into #tmpTable1 VALUES('A', 12346)
insert into #tmpTable1 VALUES('A', 12347)
insert into #tmpTable1 VALUES('A', 12348)
insert into #tmpTable1 VALUES('B', 12349)
insert into #tmpTable1 VALUES('B', 12350)
insert into #tmpTable1 VALUES('B', 12351)
insert into #tmpTable1 VALUES('B', 12352)
insert into #tmpTable1 VALUES('C', 12353)
insert into #tmpTable1 VALUES('C', 12354)
insert into #tmpTable1 VALUES('C', 12355)
insert into #tmpTable1 VALUES('C', 12356)

IF OBJECT_ID('tempdb..#tmpTable2') IS NOT NULL
  /*Then it exists*/
  DROP TABLE #tmpTable2

CREATE TABLE #tmpTable2 (
    ItemNo smallint not null,
    Value varchar(4) not null )

insert into #tmpTable2 VALUES(12345, 'S')
insert into #tmpTable2 VALUES(12346, 'S')
insert into #tmpTable2 VALUES(12347, 'I')
insert into #tmpTable2 VALUES(12348, 'B')
insert into #tmpTable2 VALUES(12349, 'I')
insert into #tmpTable2 VALUES(12350, 'S')
insert into #tmpTable2 VALUES(12351, 'S')
insert into #tmpTable2 VALUES(12352, 'S')
insert into #tmpTable2 VALUES(12353, 'S')
insert into #tmpTable2 VALUES(12354, 'S')
insert into #tmpTable2 VALUES(12355, 'S')
insert into #tmpTable2 VALUES(12356, 'S')

SQL для вашего первого условия: «получить код из таблицы1, передав ItemNo в where предложение», выбрать t1.code из # tmpTable1 t1, где t1. ItemNo = 12350

Результат: код B

SQL, чтобы добавить ваше второе условие, «извлечь все ItemNo, которые связаны с этим кодом» Использовать исходный запрос в качестве подзапроса.

select t1.ItemNo from #tmpTable1 t1 
where t1.code = (
    select t1.code from #tmpTable1 t1 
    where t1.ItemNo = 12350 )

Результат: ItemNo 12349 12350 12351 12352

SQL для добавления вашего второго условия "и, если код имеет только значение = S" Присоединитесь к таблице 2, добавьте 'S' к где. «напечатать его номер элемента и код», добавьте код к выбранному

select t1.ItemNo, t1.code from #tmpTable1 t1 
inner join #tmpTable2 t2 on t2.ItemNo = t1.ItemNo
where t1.code = (
    select t1.code from #tmpTable1 t1 
    where t1.ItemNo = 12350 )
and t2.Value = 'S'

Результат: номер элемента 12350 B 12351 B 12352 B

10
задан Lyndon 9 January 2009 в 19:34
поделиться

6 ответов

При построении на ответе ramanman вот стандартная программа, которая занимается проблемой с помощью созданного в командах файла TCL и которая работает он путь вниз дерево каталогов рекурсивно.

# findFiles
# basedir - the directory to start looking in
# pattern - A pattern, as defined by the glob command, that the files must match
proc findFiles { basedir pattern } {

    # Fix the directory name, this ensures the directory name is in the
    # native format for the platform and contains a final directory seperator
    set basedir [string trimright [file join [file normalize $basedir] { }]]
    set fileList {}

    # Look in the current directory for matching files, -type {f r}
    # means ony readable normal files are looked at, -nocomplain stops
    # an error being thrown if the returned list is empty
    foreach fileName [glob -nocomplain -type {f r} -path $basedir $pattern] {
        lappend fileList $fileName
    }

    # Now look for any sub direcories in the current directory
    foreach dirName [glob -nocomplain -type {d  r} -path $basedir *] {
        # Recusively call the routine on the sub directory and append any
        # new files to the results
        set subDirList [findFiles $dirName $pattern]
        if { [llength $subDirList] > 0 } {
            foreach subDirFile $subDirList {
                lappend fileList $subDirFile
            }
        }
    }
    return $fileList
 }
10
ответ дан 3 December 2019 в 15:07
поделиться

Это становится тривиальным с tcllib на борту:

package require fileutil
foreach file [fileutil::findByPattern $basepath *.tcl] {
    source $file
}
10
ответ дан 3 December 2019 в 15:07
поделиться

Возможно, немного более независимый от платформы и использующий builtins управляет вместо того, чтобы передать по каналу к процессу:

foreach script [glob [file join $basepath folderA *.tcl]] {
  source $script
}

Повторитесь для folderB.

Если Вы имеете более строгие критерии выбора и не волнуетесь о работе никаких других платформ, находка использования может быть более гибкой.

5
ответ дан 3 December 2019 в 15:07
поделиться

На основе предыдущего ответа эта версия обрабатывает циклы, созданные символьными ссылками, и в процессе устраняет дубликаты файлов из-за символьных ссылок также.

# findFiles
# basedir - the directory to start looking in
# pattern - A pattern, as defined by the glob command, that the files must match
proc findFiles {directory pattern} {

    # Fix the directory name, this ensures the directory name is in the
    # native format for the platform and contains a final directory seperator
    set directory [string trimright [file join [file normalize $directory] { }]]

    # Starting with the passed in directory, do a breadth first search for
    # subdirectories. Avoid cycles by normalizing all file paths and checking
    # for duplicates at each level.

    set directories [list]
    set parents $directory
    while {[llength $parents] > 0} {

        # Find all the children at the current level
        set children [list]
        foreach parent $parents {
            set children [concat $children [glob -nocomplain -type {d r} -path $parent *]]
        }

        # Normalize the children
        set length [llength $children]
        for {set i 0} {$i < $length} {incr i} {
            lset children $i [string trimright [file join [file normalize [lindex $children $i]] { }]]
        }

        # Make the list of children unique
        set children [lsort -unique $children]

        # Find the children that are not duplicates, use them for the next level
        set parents [list]
        foreach child $children {
            if {[lsearch -sorted $directories $child] == -1} {
                lappend parents $child
            }
        }

        # Append the next level directories to the complete list
        set directories [lsort -unique [concat $directories $parents]]
    }

    # Get all the files in the passed in directory and all its subdirectories
    set result [list]
    foreach directory $directories {
        set result [concat $result [glob -nocomplain -type {f r} -path $directory -- $pattern]]
    }

    # Normalize the filenames
    set length [llength $result]
    for {set i 0} {$i < $length} {incr i} {
        lset result $i [file normalize [lindex $result $i]]
    }

    # Return only unique filenames
    return [lsort -unique $result]
}
2
ответ дан 3 December 2019 в 15:07
поделиться

Вот один путь:

set includes [open "|find $basedir -name \*.tcl -print" r]

while { [gets $includes include] >= 0 } {
  source $include
}

close $includes
1
ответ дан 3 December 2019 в 15:07
поделиться

Идея такая же, как у schlenk:

package require Tclx
for_recursive_glob scriptName $basepath *.tcl {
    source $scriptName
}

Если вам нужны только папки A и B, а не другие папки в $ basepath:

package require Tclx
for_recursive_glob scriptName [list $basepath/folderA $basepath/folderB] *.tcl {
    source $scriptName
}
2
ответ дан 3 December 2019 в 15:07
поделиться
Другие вопросы по тегам:

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