1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
* ВОПРОС: У меня есть файл, который содержит имена примерно 300 файлов.
  Версии каждого из этих файлов содержатся в большинстве из 20 папок, имена которых мне также известны.
  Как мне обработать (например, объединить) файлы с одинаковыми именами из разных папок?

* ОТВЕТ. Автор: rlevesque@videotron.ca.


* Замените содержимое макроса !path на нужный корневой путь.
DEFINE !path()"D:\\data\\"!ENDDEFINE.


*************.
*Приготовим примеры файлов для иллюстрации работы решения.
*************.

DATA LIST LIST /fdrname(A12).
BEGIN DATA
"folder1"
"folderb"
"last folder"
END DATA.
LIST.

*Следующий файл будет содержать имена, скажем, 20 папок.
SAVE OUTFILE=!path + "Folder names.sav".

DATA LIST LIST /fname(A12).
BEGIN DATA
"file1"
"file2"
"another file"
"last file"
END DATA.
LIST.

* Следующий файл будет содержать имена, скажем, 300 файлов.
SAVE OUTFILE=!path + "File names.sav".

* Каждый из этих файлов находится в большинстве (но необязательно во всех) из 20 папок.

* Сделаем несколько копий самих файлов и разнесём их по некоторым папкам.
DATA LIST FREE /dummy.
BEGIN DATA
1 2 3 4 5
END DATA.

*ПРИМЕЧАНИЕ: каждый из файлов должен находиться, по крайней мере, в ПЕРВОЙ из перечисленных
* выше папок. Отсутствующие файлы могут быть сымитированы пустыми болванками с переменными, 
* но без наблюдений.
SAVE OUTFILE=!path + "folder1\\file1.sav".
SAVE OUTFILE=!path + "folderb\\file1.sav".
SAVE OUTFILE=!path + "folder1\\file2.sav".
SAVE OUTFILE=!path + "folderb\\file2.sav".
SAVE OUTFILE=!path + "last folder\\file2.sav".
SAVE OUTFILE=!path + "folder1\\another file.sav".
SAVE OUTFILE=!path + "folder1\\last file.sav".
SAVE OUTFILE=!path + "folderb\\last file.sav".


********************.
**** Начало обработки.
********************.

* Подготовим файл с именами папок.
GET FILE=!path + "Folder names.sav".
COMPUTE id=$CASENUM.
SAVE OUTFILE=!path + "folders.sav".

* Подготовим файл с именами файлов.
GET FILE=!path + "File names.sav".
* Замените 350 на некоторое целое число, не меньшее числа файлов.
LOOP id=1 TO 350.
XSAVE OUTFILE=!path + "files.sav" /KEEP id fname.
END LOOP.
EXECUTE.

GET FILE=!path + "Files.sav".
SORT CASES BY id.
MATCH FILES /FILE=*
 /TABLE=!path + 'folders.sav'
 /BY id.

SELECT IF LEN(RTRIM(fdrname))>0.
*Запишем теперь синтаксис, которые объединит все файлы в один.
SORT CASES BY fname.

MATCH FILES FILE=* /BY fname /FIRST=first /LAST=last.
STRING fullname(A80), savename(A20), quote(A1).
COMPUTE quote="'".
COMPUTE fullname=CONCAT(quote,RTRIM(fdrname),"\\",RTRIM(fname),".sav",quote).
COMPUTE savename=CONCAT(quote,RTRIM(fname),".sav",quote).

DO IF first.

WRITE OUTFILE=!path + "syntax to combine files.sps"
/ 'GET FILE="' !path '" + ' fullname '.'.
ELSE.
WRITE OUTFILE=!path + "syntax to combine files.sps"
 /'ADD FILES FILE=* /FILE="' !path '" + ' fullname '.'.
END IF.

DO IF last.
WRITE OUTFILE=!path + "syntax to combine files.sps"
 /'SAVE OUTFILE="' !path '" + ' savename '.'.
END IF.

Execute.

*Теперь загрузите синтаксис "syntax to combine files.sps"  и запустите его.
* ЗАМЕТЬТЕ, что использование команды INCLUDE для выполнения этого синтаксиса 
* НЕ сработает из-за наличия пропущенных файлов.