원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보 질문입니다.안녕하세요 여러분, 이것이 이 커뮤니티의 첫 번째 게시물입니다. 저는 최근에 직장을 바꾸었고 프로버 벤치 테스트와 데이터 분석을 많이 할 예정입니다. JMP를 조금 사용했지만 전혀 발전된 것이 없습니다.
현재 내 테스트에서는 항상 큰 CSV 파일이 생성되고 측정 데이터는 관심 없는 정보(예: 테스트 설정, 조건 등)와 함께 묻혀 있습니다. JMP 스크립트를 사용하여 유용한 정보를 추출하는 데 도움을 받고 싶습니다. 여기에서 고급 스크립트 학습을 시작하세요.
첨부된 스크린샷에서 내 작업을 설명합니다. 오른쪽 상단은 내 거대한 CVS가 어떻게 생겼는지에 대한 아이디어를 제공하기 위한 단일 IV 스윕 데이터 포인트 예(R을 측정하기 위한)입니다(수백 개의 이러한 구조가 포함되어 있음). "다중 행 무관 정보"는 가져오고 싶지 않은 쓸모 없는 행을 나타냅니다. I/V/R 데이터 부분을 복사하여 붙여넣는 것 외에도 일부 문자열에서 웨이퍼 로트 ID, 웨이퍼 ID, 레티클(또는 스테퍼 필드) 인덱스 및 하위 사이트 번호를 추출하는 것도 좋아합니다. 오른쪽 상단 상자에는 원하는 JMP 출력이 표시됩니다.
선택적으로 읽을 수 있는 내용으로 아래쪽 두 상자에 몇 가지 퀴즈가 있습니다. 왼쪽 하단은 데이터 구조에 대한 일반적인 설명이고 오른쪽 하단은 특정 정보를 추출하는 데 필요한 문자열의 의미를 설명합니다.
스크린샷이 제 질문에 대한 충분한 정보를 제공해주기를 바랍니다. 저는 Excel VBA 매크로를 사용하여 이러한 작업을 수행했습니다. 검색 서명 문자열을 스캔한 다음 해당 위치 근처의 특정 문자/문자열/행을 선택적으로 가져온 다음 원시 데이터 파일이 끝날 때까지 검색을 계속했습니다. JMP 스크립트도 같은 기능을 수행할지 궁금합니다.
자동화 및 스크립팅Re: 원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보 질문입니다.스크린샷이 없습니다. 소규모의 익명화된 데이터 세트 또는 .csv 파일을 첨부할 수 있습니까?
Re: 원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보 질문입니다.안녕하세요 pmroz, 신속한 답변에 감사드립니다. 처음 제출할 때 첨부 파일을 잊어버렸는데 1분 안에 게시물을 편집하고 스크린샷을 첨부했습니다. 다시 확인하실 수 있습니다.
또한 귀하의 요청에 따라 여기에 Excel을 업로드합니다. 파일을 깔끔하게 만들기 위해 대부분의 쓸모 없는 정보를 삭제했지만 왼쪽 상단 상자를 "원시 데이터" 예로 복사하여 붙여넣을 수 있습니다.
Re: 원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보 질문입니다.표시되는 형식은 읽기에 큰 문제가 되어서는 안 됩니다. 흥미롭지 않은 정보 행은 데이터 읽기를 방해할 수 있기 때문에 걱정됩니다. 또 다른 관심사는 JMP가 프로젝트 이름이 포함된 행을 인식하도록 하는 방법입니다. 항상 Proj로 시작하나요?
실제 파일을 제공하면 매우 도움이 될 것입니다.
Re: 원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보 질문입니다.다른 사람들이 말했듯이 이는 실제 데이터 형식에 따라 크게 달라질 수 있습니다. 다음은 Excel에서 텍스트 파일로 붙여넣은 데이터 복사본을 사용한 예입니다.
Names Default To Here(1);
filepath = "$DOWNLOADS/744027.txt";
txt = Load Text File(filepath);
lines = Words(txt, "\!N");
project_pattern = "^(.+)_(\d+\.\d*)(W\d{1,2})_(T\d+)_(.+):(.+)?";
subsite_pattern = "<SUBSITE>(\d+)</SUBSITE>";
datastart_pattern = "^DataName";
data_start = 0;
For Each({line, idx}, lines,
If(!IsMissing(Regex(line, project_pattern)),
matches = Regex Match(line, project_pattern);
projname = matches[2];
lotid = matches[3];
waferid = matches[4];
time = matches[5];
notes = matches[6];
reticles = Words(Trim Whitespace(matches[7]), " ");
, !IsMissing(Regex(line, subsite_pattern)),
subsite = Regex(line, subsite_pattern, "\1");
, !IsMissing(Regex(line, datastart_pattern)),
data_start = idx;
break();
);
);
data_str = Concat Items(lines[data_start::N Items(lines)], "\!N");
dt = Open(Char To Blob(data_str), "text");
dt << New Column("lot", Character, Nominal, Set Each Value(lotid));
dt << New Column("waferid", Character, Nominal, Set Each Value(waferid));
dt << New Column("x", Character, Nominal, Set Each Value(reticles[1]));
dt << New Column("y", Character, Nominal, Set Each Value(reticles[2]));
dt << New Column("subsite", Character, Nominal, Set Each Value(subsite));
dt << Move Selected Columns({:lot, :waferid, :x, :y, :subsite}, To First);
dt << Delete Columns("DataName");
정규식을 사용하여 특정 줄을 찾은 다음 구문 분석합니다. 데이터의 경우 시작되는 라인 인덱스를 찾은 다음 JMP가 열도록 하여 이를 구문 분석합니다(실제 데이터에 따라 추가 단계가 필요할 수 있음).

Re: 원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보자 질문- 하위 사이트를 간과했습니다. 죄송합니다. 스크립트에 추가했습니다.
- 토론 포럼의 목적은 JMP 사용자가 JMP를 실행하는 데 문제가 있는 경우 이를 해결하는 데 도움을 주는 것입니다. 무료 스크립트 작성 서비스는 아닙니다. 커뮤니티 멤버를 위해 스크립트를 작성하는 이유는 JSL을 사용하는 방법을 가르치기 위해서입니다. 제가 제공하는 스크립트를 받는 사람이 시간을 내어 스크립트에서 배우고 전체 문제를 해결할 수 있기를 바랍니다.
- 동적 열(부분 열 속성)을 숫자형으로 변경했습니다.
- 이제 스크립트는 생성된 각 테이블을 함께 추가합니다.
- 코드 압축에 관해서.....왜? 압축의 목적이 코드를 더 빨리 실행하게 하는 것이라면, 저는 그걸 따를 수 있습니다. 하지만 코드를 압축하면 그것을 봐야 할 다음 사람이 읽기 어려워진다면, 그 코드는 좋은 코드가 아닙니다. 따라서 코드를 더 간결한 형식으로 압축할 수 있느냐는 질문에 대한 제 답변은, 그럴 수 있다고 확신한다는 것입니다.
names default to here(1);
clear symbols( dtOut );
file = pick file();
dt = Open(
File,
Import Settings(
End Of Line( CRLF, CR, LF ),
End Of Field( Comma, CSV( 0 ) ),
Treat Leading Zeros as Character( 1 ),
Strip Quotes( 1 ),
Use Apostrophe as Quotation Mark( 0 ),
Use Regional Settings( 0 ),
Scan Whole File( 1 ),
Treat empty columns as numeric( 0 ),
CompressNumericColumns( 0 ),
CompressCharacterColumns( 0 ),
CompressAllowListCheck( 0 ),
Labels( 0 ),
Column Names Start( 1 ),
First Named Column( 1 ),
Data Starts( 1 ),
Lines To Read( "All" ),
Year Rule( "20xx" )
)
);
// Change column names to simplify coding
for( i=1,i<=ncols(dt), i++, column(i)<< set name( "C" || char(i)));
// Create a base output table
dtFinal = New Table( "Final" );
// Loop through the data
for(theRow = 1, theRow <= NRows(dt), theRow++,
If( dt:C1[theRow] == "SetupTitle",
memoryProjectName = "";
memoryLotName = "";
memoryWaferID = "";
memoryT0 = "";
memory1strun = "";
memoryIndexX = .;
memoryIndexY = .;
memorySubsite = .;
setupFlag = 1;
projFlag = 0;
// If this is not the first read in table, then append the table
// to the Final table, and close the current dtOut table
If( nrows(dtFinal) != 0 | isEmpty( dtOut ) == 0,
dtFinal << concatenate( dtOut, append to first table(1));
close( dtOut, nosave )
)
,
dt:C1[theRow] == "" & setupFlag == 1,
projFlag = 1;
setupFlag = 0;
,
projFlag == 1 & dt:C1[theRow] != "",
dt:C1[theRow] = trim(dt:C1[theRow]);
memoryProjectName = word(1, dt:C1[theRow], "_");
memoryLotName = word(2, dt:C1[theRow], "_W");
memoryWaferID = word(3, dt:C1[theRow], "_W");
memoryT0 = word(4, dt:C1[theRow], "_W");
memory1strun = word(5, dt:C1[theRow], "_W:");
memoryIndexX = num(word(2, dt:C1[theRow], ": "));
memoryIndexY = num(word(3, dt:C1[theRow], ": "));
memorySubsite = num(word(2, trim(dt:C1[theRow + 2 ]),"<>"));
projFlag = 0;
,
dt:C1[theRow] == "DataName",
colList = {};
col=2;
while( column(dt,col)[theRow] != "",
insert into(colList, column(dt,col)[theRow]);
col++
);
dtOut = New Table( "Lot " || memoryLotName || " WaferID " || memoryWaferID,
new column( "Project Name", character),
new column( "Lot Name", character),
new column( "WaferID", character),
new column( "Time Readout", character),
new column( "Personal Note", character),
new column( "SubSite", numeric, ordinal),
new column( "Index X", numeric, ordinal),
new column( "Index Y", numeric, ordinal)
);
for each( {colName}, colList,
dtOut << new column( eval(colName), numeric, continuous);
);
,
dt:C1[theRow] == "DataValue",
dtOut << Add Rows(1);
dtOut:Project Name[nrows(dtOut)] = memoryProjectName;
dtOut:Lot Name[nrows(dtOut)] = memoryLotName;
dtOut:WaferID[nrows(dtOut)] = memoryWaferID;
dtOut:Time Readout[nrows(dtOut)] = memoryT0;
dtOut:Personal Note[nrows(dtOut)] = memory1strun;
dtOut:SubSite[nrows(dtOut)] = memorysubsite;
dtOut:Index X[nrows(dtOut)] = memoryIndexX;
dtOut:Index Y[nrows(dtOut)] = memoryIndexY;
for each( {colName, index}, colList,
column( dtOut, colName )[nrows(dtOut)] = num(column(dt,index+1)[theRow])
)
)
);
// Close the last work file
close( dtOut, nosave );
// Uncomment the below line if you want the raw table deleted
// close( dt, nosave );
Re: 원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보자 질문이전 아이디어를 이어가며 텍스트 파일을 섹션으로 나눈 다음 해당 섹션을 구문 분석해 보겠습니다(이 녹음은 부분적으로 이 주제인 Scripters Club 2024: 세션 2 - 분석을 위한 비정형 수신 데이터 준비에 대한 내용을 다룹니다).
Names Default To Here(1);
// Test sections seem to always start with a line starting with "SetupTitle"
// and end to same UNLESS it is last section when it ends with
// line of ",,,,,,,,,,,,,,,,,,,,,,,"
TEST_SECTION_START = "SetupTitle, ";
EMPTY_LINE = ",,,,,,,,,,,,,,,,,,,,,,,";
// Section patterns for regex
PROJECT_PATTERN = "^(.+)_(\d+\.\d*)(W\d{1,2})_(T\d+)_(.+): (\d+ \d+)\,+?";
SUBSITE_PATTERN = "<SUBSITE>(\d+)</SUBSITE>";
DATASTART_PATTERN = "^DataName";
find_test_section_lines = function({lines}, {Default Local},
start_idx = 0;
end_idx = 0;
TEST_SECTION_START = TEST_SECTION_START; // JMP "feature", 00075244
TEST_SECTION_END = TEST_SECTION_END; // JMP "feature", 00075244
For Each({line, idx}, lines,
If(Starts With(line, TEST_SECTION_START),
If(start_idx == 0,
start_idx = idx;
,
end_idx = idx;
break();
);
);
);
If(start_idx != 0 & end_idx == 0,
end_idx = N Items(lines);
);
return(Eval List({start_idx, end_idx}));
);
parse_test_section = function({lines}, {Default Local},
data_start = 0;
PROJECT_PATTERN = PROJECT_PATTERN; //JMP "feature", 00075244
SUBSITE_PATTERN = SUBSITE_PATTERN; //JMP "feature", 00075244
DATASTART_PATTERN = DATASTART_PATTERN; //JMP "feature", 00075244
For Each({line, idx}, lines,
If(!IsMissing(Regex(line, PROJECT_PATTERN)),
matches = Regex Match(line, PROJECT_PATTERN);
projname = matches[2];
lotid = matches[3];
waferid = matches[4];
time = matches[5];
notes = matches[6];
reticles = Words(Trim Whitespace(matches[7]), " ");
, !IsMissing(Regex(line, SUBSITE_PATTERN)),
subsite = Regex(line, SUBSITE_PATTERN, "\1");
, !IsMissing(Regex(line, DATASTART_PATTERN)),
data_start = idx;
break();
);
);
data_str = Concat Items(lines[data_start::N Items(lines)], "\!N");
dt = Open(Char To Blob(data_str), "text", invisible);
For Each({colname}, Reverse(dt << Get Column Names("String")), // drop empty columns
If(Col Number(Column(dt, colname)) == 0,
dt << Delete Column(colname);
,
break(); // break on first "ok" column
);
);
// define order and names here
dt << New Column("project", Character, Nominal, Set Each Value(projname));
dt << New Column("lot", Character, Nominal, Set Each Value(lotid));
dt << New Column("waferid", Character, Nominal, Set Each Value(waferid));
dt << New Column("time", Character, Nominal, Set Each Value(time));
dt << New Column("notes", Character, Nominal, Set Each Value(notes));
dt << New Column("x", Character, Nominal, Set Each Value(reticles[1]));
dt << New Column("y", Character, Nominal, Set Each Value(reticles[2]));
dt << New Column("subsite", Character, Nominal, Set Each Value(subsite));
dt << Move Selected Columns({:project, :lot, :waferid, :time, :notes, :x, :y, :subsite}, To First);
dt << Delete Columns("DataName");
return(dt);
);
// Start parsing
filepath = "$DOWNLOADS/Raw data examples_3DP.csv";
txt = Load Text File(filepath);
lines = Words(txt, "\!N");
lines = Filter Each({line}, lines, line != EMPTY_LINE); // drop empty lines
{start, end} = find_test_section_lines(lines);
dt_result = Empty();
While(All(start, end),
cur_testset = Remove From(lines, start, end - 1);
dt = parse_test_section(cur_testset);
If(Is Empty(dt_result),
dt_result = dt;
,
dt_result << Concatenate(
dt,
"Append to first table"
);
Close(dt, no save);
);
{start, end} = find_test_section_lines(lines);
);
dt_result << Show Window(1);

Re: 원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보자 질문다음은 샘플 CSV 파일에서 찾은 3개의 프로젝트 데이터를 모두 읽고 3개의 별도 데이터 테이블을 만드는 스크립트입니다.
names default to here(1);
file = pick file();
dt = Open(
File,
Import Settings(
End Of Line( CRLF, CR, LF ),
End Of Field( Comma, CSV( 0 ) ),
Treat Leading Zeros as Character( 1 ),
Strip Quotes( 1 ),
Use Apostrophe as Quotation Mark( 0 ),
Use Regional Settings( 0 ),
Scan Whole File( 1 ),
Treat empty columns as numeric( 0 ),
CompressNumericColumns( 0 ),
CompressCharacterColumns( 0 ),
CompressAllowListCheck( 0 ),
Labels( 0 ),
Column Names Start( 1 ),
First Named Column( 1 ),
Data Starts( 1 ),
Lines To Read( "All" ),
Year Rule( "20xx" )
)
);
// Change column names to simplify coding
for( i=1,i<=ncols(dt), i++, column(i)<< set name( "C" || char(i)));
// Loop through the data
for(theRow = 1, theRow <= NRows(dt), theRow++,
If( dt:C1[theRow] == "SetupTitle",
memoryProjectName = "";
memoryLotName = "";
memoryWaferID = "";
memoryT0 = "";
memory1strun = "";
memoryIndexX = .;
memoryIndexY = .;
setupFlag = 1;
projFlag = 0;
,
dt:C1[theRow] == "" & setupFlag == 1,
projFlag = 1;
setupFlag = 0;
,
projFlag == 1 & dt:C1[theRow] != "",
dt:C1[theRow] = trim(dt:C1[theRow]);
memoryProjectName = word(1, dt:C1[theRow], "_");
memoryLotName = word(2, dt:C1[theRow], "_W");
memoryWaferID = word(3, dt:C1[theRow], "_W");
memoryT0 = word(4, dt:C1[theRow], "_W");
memory1strun = word(5, dt:C1[theRow], "_W:");
memoryIndexX = num(word(2, dt:C1[theRow], ": "));
memoryIndexY = num(word(3, dt:C1[theRow], ": "));
projFlag = 0;
,
dt:C1[theRow] == "DataName",
colList = {};
col=2;
while( column(dt,col)[theRow] != "",
insert into(colList, column(dt,col)[theRow]);
col++
);
dtOut = New Table( "Lot " || memoryLotName || " WaferID " || memoryWaferID,
new column( "Project Name", character),
new column( "Lot Name", character),
new column( "WaferID", character),
new column( "Time Readout", character),
new column( "Personal Note", character),
new column( "Index X", numeric, ordinal),
new column( "Index Y", numeric, ordinal)
);
for each( {colName}, colList,
dtOut << new column( eval(colName), numeric, continuous);
);
,
dt:C1[theRow] == "DataValue",
dtOut << Add Rows(1);
dtOut:Project Name[nrows(dtOut)] = memoryProjectName;
dtOut:Lot Name[nrows(dtOut)] = memoryLotName;
dtOut:WaferID[nrows(dtOut)] = memoryWaferID;
dtOut:Time Readout[nrows(dtOut)] = memoryT0;
dtOut:Personal Note[nrows(dtOut)] = memory1strun;
dtOut:Index X[nrows(dtOut)] = memoryIndexX;
dtOut:Index Y[nrows(dtOut)] = memoryIndexY;
for each( {colName, index}, colList,
column( dtOut, colName )[nrows(dtOut)] = column(dt,index+1)[theRow]
)
)
);
Re: 원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보자 질문안녕 txnelson , 잘 말씀하셨네요. 제 게으름에 대해 사과드립니다. 시간을 들이면 제가 스스로 답을 알아낼 수 있다는 걸 알지만(그리고 장기적으로는 제게 도움이 됩니다) 가능한 한 빨리 정답을 얻어야 한다는 압박감을 느꼈습니다.
경험이 쌓이면 돌아와서 새로운 사람들을 도울 것입니다. 저는 이것이 모두가 서로를 돕는 진정한 사용자 커뮤니티라고 생각합니다. 각 답변은 개별적인 필요에 맞게 맞춤화되어 있습니다. JMP는 여기의 활동적인 사용자에게 인센티브를 제공해야 합니다. 이 스레드에서 귀하의 답변이 다른 엔지니어 사용자에게도 도움이 되기를 바랍니다.
Re: 원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보자 질문안녕 txnelson , 잘 됩니다! 다음 주 보고서에 이 스크립트가 정말 필요할 겁니다. 감사합니다!!!~~~
그동안, 너무 복잡하지 않다면 약간의 개선을 해 주실 수 있을까요?
1. 하위 사이트 정보(열)가 누락되었습니다.
//미래 시청자를 돕기 위해, 하나의 웨이퍼에는 여러 개의 레티클(스테퍼 필드 또는 다이라고도 함)이 있습니다. 각 레티클에는 고유한(인덱스 X, 인덱스 Y)이 있습니다. 각 레티클에는 "서브사이트"(서브다이라고도 함)라는 수많은 장치가 있습니다. 측정은 서브사이트-레티클-웨이퍼별로 수행됩니다.

2. 모든 DP를 단일 JMP 테이블로 출력
//너무 깊이 생각하지 않고 전체 원시 파일(수백 개의 DP...)에 스크립트를 적용했는데, 무슨 일이 일어났는지 상상하실 수 있을 겁니다. 끊임없이 뜨는 JMP 창과 싸운 끝에 결국 작업 관리자를 켜서 항복했죠...
3. 데이터 테이블 부분 열 속성을 문자에서 숫자로 변경합니다.
4. 코딩을 더 간결한 형식으로 압축할 수 있나요?
//현재의 것은 매우 직관적이고 초보자인 저에게는 좋습니다. 하지만, 나중에 더 짧은 코드가 더 사용자 친화적일 수 있습니다. 복잡하거나 더 이상 처음 보는 사람에게 친화적이지 않다면 잊어주세요.
Re: 원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보자 질문안녕 jthi , 고맙습니다! 나중에 이 정규식 함수에 대해 배우는 데 시간을 투자하겠습니다.
이 스레드가 필요한 답변을 제공할 뿐만 아니라(정말 감사합니다) 비슷한 스캔-앤-추출 JMP 작업을 위한 시작 템플릿 역할을 하기를 바랍니다. 미래의 작업을 위해 모든 스크립트를 저장할 것입니다!
이 주제에 더 기여하기 위해, 제가 이런 스크립트를 사용할 때 가장 가능성 있는 문제는 Job id 형식 일관성 입니다. Job ID를 구성하는 방법에 주의를 기울이고 임의로 변경하지 마세요. 따르지 않으면 프로그래밍이 왜곡될 수 있습니다. 두 가지 예를 들자면, 제 Job id 표준 형식은 다음과 같습니다. Projname_Lot id_wafer id_personal note: index X index Y
하지만 이것은 벤치 테스트이고 제가 모든 테스트에 수동으로 이름을 지정했기 때문에 제가 규칙을 위반하고 위의 스타일을 정확히 따르지 않은 경우가 몇 가지 있었습니다.
1. 로트 ID와 웨이퍼 ID 사이에 "_"를 놓쳤습니다. 예를 들어, "753367.1_W11" 대신 어떤 경우에는 "753367.1W11"을 입력했습니다.
2. 개인 메모를 하나 대신 두 개 추가했습니다. 예를 들어, 1차 실행 후 재테스트할 때 "_2nd_" 대신 "_1st_redo_"를 사용했습니다. 정보 섹션 구분자로 "_"를 사용하기 때문에 해당 섹션과 그 뒤에 오는 모든 것이 계산이 엉망이 되어 문제가 될 것입니다.
고급 JMP 스크립팅의 첫걸음을 내딛는 데 도움을 준 jthi와 txnelson에게 다시 한번 감사드립니다!
Re: 원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보자 질문애플리케이션에 따라 특정 줄과 일치하는 정규식 패턴에 의존하는 대신 반복되는 패턴을 찾아 파서를 더욱 강력하게 만들 수 있습니다. 예를 들어 프로젝트 이름이 MetaData 줄 사이에 있는 것 같습니다.

귀하가 내리는 가정에 따라 "줄이 Proj로 시작함"이나 "줄이 이 정규식 패턴과 일치함"에 의존하는 대신 해당 MetaData와 "빈" 줄을 기준으로 추출할 수 있습니다.
Re: 원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보자 질문안녕하세요, Jthi,
이 스크립트를 실행하면 왜 이런 오류가 발생하는지 알려주세요.

Re: 원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보자 질문흥미로운 지적이네요, jthi. 생각해 볼게요.
정보가 작업 ID 줄에 내장되어 있다는 점에 유의하세요. 가장 큰 문제는 정보를 찾는 것이 아니라 추출하는 방법입니다. 제가 배운 것은 "Proj로 시작하는 줄"의 일관성을 유지하는 것입니다. 매우 매우 중요합니다. 이를 다시 한번 확인하기 위해 패턴 검증 스크립트를 추가하고 추출된 정보가 예상 범위 내에 있는지 확인할 수 있습니다. 정규식은 이러한 목적에 직관적인 도구입니다.
Re: 원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보자 질문TEST_SECTION_END를 정의하셨나요?
Re: 원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보자 질문네, 이전에 게시하신 것과 동일한 스크립트를 사용하고 있습니다.

Re: 원시 프로브 데이터에서 데이터 테이블 생성(추출)에 대한 초보자 질문아.. 제 스크립트에서 어떤 이유에서인지 삭제된 것 같은데, TEST_SECTION_END를 확인해야 합니다. 얼핏 보면 EMPTY_LINE과 같은 것 같습니다.