txt 파일에 다음과 같은 데이터 덩어리가 있습니다.
Informatica(r) PMCMD, version [9.5.1 HotFix4], build [313.0217], SOLARIS 64-bit
Copyright (c) Informatica Corporation 1994 - 2014
All Rights Reserved.
Invoked at Wed Dec 30 11:13:42 2015
Connected to Integration Service: [TEST_Integration_Service].
Integration Service status: [Running]
Integration Service startup time: [Sun Dec 27 06:37:32 2015]
Integration Service current time: [Wed Dec 30 11:13:42 2015]
Folder: [ALS_DIM]
Workflow: [wf_ld_als_dim] version [1].
Workflow run status: [Scheduled]
Workflow run error code: [0]
Workflow run id [0].
Schedule time: [Wed Dec 30 19:00:00 2015]
Workflow run type: [Schedule]
Run workflow as user: [Administrator]
Run workflow with Impersonated OSProfile in domain: []
Integration Service: [TEST_Integration_Service]
Folder: [ALS_FACT]
Workflow: [wf_s_m_ld_interchanges_detail_log] version [1].
Workflow run status: [Scheduled]
Workflow run error code: [0]
Workflow run id [0].
Schedule time: [Mon Jan 04 16:30:00 2016]
Workflow run type: [Schedule]
Run workflow as user: [Administrator]
Run workflow with Impersonated OSProfile in domain: []
Integration Service: [TEST_Integration_Service]
Folder: [ALS_PRD]
Workflow: [wf_maint_service_fields] version [1].
Workflow run status: [Scheduled]
Workflow run error code: [0]
Workflow run id [0].
Schedule time: [Thu Dec 31 07:10:00 2015]
Workflow run type: [Schedule]
Run workflow as user: [Administrator]
Run workflow with Impersonated OSProfile in domain: []
Integration Service: [TEST_Integration_Service]
Number of scheduled workflows on this Integration Service: [3]
Disconnecting from Integration Service
반복될 때마다 폴더명, 워크플로우명, 워크플로우 실행 상태, 예약 시간, 통합 서비스 이름만 순서대로 추출되도록 데이터를 다른 텍스트 파일로 추출해야 합니다.
예를 들어:
Insert into <tablename> values('ALS_DIM', 'wf_ld_als_dim', 'Scheduled', 'Wed Dec 30 19:00:00 2015', 'TEST_Integration_Service')
이는 첫 번째 그룹 등에 대해 가져와야 합니다.
저는 주어진 3개의 데이터 세트에 특정한 스크립트를 개발했지만 이를 통해 스크립트가 원하는 수의 데이터 세트에 대해 실행될 수 있어야 합니다.
저는 쉘 스크립팅에 대해 매우 기초적인 지식을 갖고 있으므로 이에 대한 도움을 받는 것이 좋을 것입니다.
답변1
일방 sed
통행...
sed -ne'/^Folder: *\[/!{' \
-e'/^Workflow\( run status\)\{0,1\}: *\[/!{' \
-e'/^Schedule time: *\[/!{' \
-e'/^Integration Service: *\[/!d' \
-e\} -e\} -e\} -e"s//'/" -e"s/\].*/'/" -e'H;x' \
-e'/ .*\n.*/h' -e's///' -e'x' \
-e's//Insert into <tablename> values(&)/' \
-e's/\n//' -e's//, /gp'
Insert into <tablename> values('ALS_DIM', 'wf_ld_als_dim', 'Scheduled', 'Wed Dec 30 19:00:00 2015', 'TEST_Integration_Service')
Insert into <tablename> values('ALS_FACT', 'wf_s_m_ld_interchanges_detail_log', 'Scheduled', 'Mon Jan 04 16:30:00 2016', 'TEST_Integration_Service')
Insert into <tablename> values('ALS_PRD', 'wf_maint_service_fields', 'Scheduled', 'Thu Dec 31 07:10:00 2015', 'TEST_Integration_Service')
따라서 첫 번째 줄은 다음과 같은 허용 가능한 일치 항목을 무효화합니다.
if ! match ^Folder: *\[
then if ! match ^Workflow: *\[ or ^Workflow run status: *\[
then if ! match ^Schedule time: *\[
then if ! match ^Integration Service: *\[
then delete
fi
fi
fi
fi
그러나 라인이 체인 중 하나와 일치하면 체인이 끊어지고 끝까지 이동할 수 없습니다. 이는 주어진 일치 행에 대해 테스트된 마지막 정규식이 닫는 대괄호까지 해당 행의 선두를 설명한다는 것을 의미합니다. sed
스크립트 에서는 빈 주소를 사용하여 가장 최근에 컴파일된 정규식을 다시 참조할 수 있습니다 //
. 나는 그것을 바꾸고 s//'/
원하는 출력의 선행 따옴표 로 바꾸겠습니다 .'
남은 것은 원하는 모든 정보와 ]
각 줄의 첫 번째 줄 뒤의 후행 컨텍스트뿐입니다. 그래서 각 줄의 원치 않는 꼬리도 s/\].*/'/
후행 인용문으로 대체했습니다.'
이 시점에서 모든 선은 원하는 부분으로 제거되었지만 아직 연결되지 않았습니다. 이를 달성하기 위해 H
행 주기를 유지하는 이전 공간을 사용했습니다 . 따라서 각 행의 복사본을 H
이전 공간 에 추가하고 x
보존 및 모드 버퍼를 변경한 / .*\n.*/
다음<스페이스>그 다음에<줄 바꿈>- 날짜 표시줄 다음 예약된 줄에서만 발생합니다.
패턴이 발견되면 h
이전 공간을 덮어쓰고 s///
교체합니다 .모두패턴 공간(이 반복의 마지막 행이므로 다음 반복을 위해 비워 두십시오.). 여기에 빈 주소가 있으면 s///
해당 주소와 일치하는 줄의 내용만 삭제됩니다.<스페이스> + <줄 바꿈>패턴 - 따라서 각 반복의 마지막 줄에서만 이러한 명령이 성공할 수 있습니다.
어쨌든, 나중에 x
마지막으로 홀드 버퍼와 패턴 버퍼를 변경했으므로 이제 패턴 버퍼에는 이 반복에 대한 모든 일치 항목이 다음과 같이 구분되어 포함됩니다.<줄 바꿈>그렇지 않으면 가장 가까운 일치 항목과 0만 포함됩니다.<줄 바꿈>수치. 이것이 이 반복에 대한 마지막 일치 라인인 경우 이 지점의 보유 버퍼는 비어 있습니다. 그렇지 않으면 지금까지 일치하는 모든 라인을 포함하며 각 라인에는 선행 접두사가 붙습니다.<줄 바꿈>.
다음으로 동일한 정규식을 다시 인용하고 다음으로 바꾸려고했습니다.<스페이스> + <줄 바꿈>자신만의 패턴으로 포장된Insert into <tablename> values(
그리고 후행)
.
s///
마지막으로, 나는 선두를 교체하지 않을 것 입니다 .<줄 바꿈>마지막으로 일치하는 줄의 패턴 공간에 있고 나머지는 모두<줄 바꿈>쉼표 다음<스페이스>각. s///
대체가 성공하면 그 결과가 표준 p
출력으로 인쇄됩니다.
답변2
펄 방법:
$ perl -lne 'if(/^(Folder|Workflow|Workflow.*?status|Sched.*time|Integration Service):.*?\[([^][]+)/){++$k%5==0 ? print "$2" : printf "%s,",$2}' file
ALS_DIM, wf_ld_als_dim, Scheduled, Wed Dec 30 19:00:00 2015, TEST_Integration_Service
ALS_FACT, wf_s_m_ld_interchanges_detail_log, Scheduled, Mon Jan 04 16:30:00 2016, TEST_Integration_Service
ALS_PRD, wf_maint_service_fields, Scheduled, Thu Dec 31 07:10:00 2015, TEST_Integration_Service
또는 더 간결하게 말하면:
$ perl -lne '
if(/^ ## Match the beginning of the line
( ## 1st capturing group: $1
Folder | ## The various things we want to match
Workflow |
Workflow.*?status |
Sched.*time |
Integration\s*Service
): ## Only if they are followed by a :
.*?\[
( ## 2nd caprturing group: $2.
[^][]+ ## The longest string of non-] or [
)/x ## The x allows writing multiline regexes
)
{ ## If this line matches...
$k=$k+1; ## Increment the counter $k by one
if($k%5==0){ ## If the current value of $k is a multiple of 5.
print "$2" ## Print the 2nd captured group and a newline.
} ## The newline is automatically added by the -l.
else{
printf "%s,",$2 ## For other lines, just print with no newline.
}
}' file
ALS_DIM, wf_ld_als_dim, Scheduled, Wed Dec 30 19:00:00 2015, TEST_Integration_Service
ALS_FACT, wf_s_m_ld_interchanges_detail_log, Scheduled, Mon Jan 04 16:30:00 2016, TEST_Integration_Service
ALS_PRD, wf_maint_service_fields, Scheduled, Thu Dec 31 07:10:00 2015, TEST_Integration_Service
을 추가하려면 Insert ...
간단한 패스를 전달하면 됩니다 sed
.
$ perl -lne 'if(/^(Folder|Workflow|Workflow.*?status|Sched.*time|Integration Service):.*?\[([^][]+)/){++$k%5==0 ? print "$2" : printf "%s,",$2}' file |
sed "s/^/Insert into <tablename> values('/; s/,/','/g; s/$/')/"
Insert into <tablename> values("ALS_DIM","wf_ld_als_dim","Scheduled","Wed Dec 30 19:00:00 2015","TEST_Integration_Service")
Insert into <tablename> values("ALS_FACT","wf_s_m_ld_interchanges_detail_log","Scheduled","Mon Jan 04 16:30:00 2016","TEST_Integration_Service")
Insert into <tablename> values("ALS_PRD","wf_maint_service_fields","Scheduled","Thu Dec 31 07:10:00 2015","TEST_Integration_Service")
sed
세 가지 대체 연산자를 실행합니다 .
s/^/Insert into <tablename> values("/
:^
줄의 시작 부분입니다. 따라서s/^/foo/
줄의 시작 부분에 삽입하십시오.foo
여기에 삽입하고 있습니다nsert into <tablename> values("
.s/,/','/g
: (s///g
) 쉼표를 모두 로 바꿉니다','
.s/$/")/'
:$
줄의 끝이므로)"
맨 끝에 추가됩니다.