배치 스크립트를 사용하여 문자열을 어떻게 구문 분석할 수 있나요?
목표는 아래의 모든 항목을 배열에 저장 Import:
하고 --> 및 #head
와 같이 제거하는 것입니다 .//MPackages/Project/config/abc.txt
//Packages/Project/config/cde.txt
테스트.txt:
Version: 4.5.0
Import:
//MPackages/Project/config/abc.txt #head
//Packages/Project/config/cde.txt #head
View:
//MPackages/Project/config/ac.txt #head
//Packages/Project/config/de.txt #head
내 시도:
@echo off
set buildlog="devel.p4inc"
setlocal EnableDelayedExpansion
for /F "tokens=*" %%A in (devel.p4inc) do (
if /i "%%A"=="Import:" set "import=true"
IF DEFINED import (echo %%A)
)
원하는 출력
//MPackages/Project/config/abc.txt
//Packages/Project/config/cde.txt
가져오기 아래의 모든 항목:
답변1
논리의 주요 문제 중 하나는 무언가가 참인 경우 "가져오기" 변수를 한 번 설정하고 재설정하지 않거나 더 이상 참이 아닌 경우 정의를 해제한다는 것입니다. 따라서 처음 설정된 후에는 루프의 나머지 부분에 대해 "정의된" 상태로 유지됩니다.
내가 선호하는 것은 변수를 구체적으로 설정하는 것입니다( true
또는 false
). 시작 하도록 설정 false
한 다음 원하는 대로 설정 하고 필요할 때 true
다시 설정하도록 하세요 . false
그런 다음 루프를 반복할 때마다 변수가 방금 정의되었는지 확인하는 대신 True
변수 가 구체적으로 설정되었는지 확인합니다.False
이 코드는 귀하의 정보/목표에 따라 작동합니다.
@echo off
setlocal EnableDelayedExpansion
set buildlog=test.txt
set import=false
for /F "tokens=*" %%A in (%buildlog%) do (
if /i "%%A"=="Import:" (
set import=true
)
if /i "%%A"=="View:" (
set import=false
)
if !import!==true (
if not "%%A"=="Import:" (
for /F "tokens=1" %%B in ("%%A") do (
echo %%B
)
)
)
)
의도적으로 "가져오기" 변수(플래그)를 false
시작하도록 설정했습니다.
첫 번째 For 루프는 파일의 각 라인을 통과합니다( test.txt
이 예에서는 "buildlog" 변수로 지정됨. 참고: For 루프에서 작동하려면 변수에서 파일 이름 주위의 따옴표를 제거해야 함) .
첫 번째 IF는 현재 줄이 "Import:" 줄인지 확인하고, 그렇다면 "import" 플래그를 로 바꿉니다 true
.
다음 IF는 현재 행이 "View:" 행인지 확인하고, 그렇다면 "가져오기" 플래그를 (다시) 로 전환하여 false
각 행 처리를 중지합니다.
세 번째 IF는 해당 "import" 플래그가 인지 확인하고 true
, 그렇다면 라인을 처리합니다.
그렇다면 true
중첩된(4번째) IF는 해당 행이 실제 "import:" 행인지 확인하고, 그렇지 않은 경우 해당 행을 표시합니다(출력에 "Import:" 행이 표시되지 않도록 합니다).
두 번째 For 루프는 표시하려는 라인을 통과하고 원하는 경로인 첫 번째 토큰 세트만 가져오고 #head
.
추가/관련 정보:
댓글 후 수정:
"View:" 줄 뒤에 버전 번호가 있는 경우 이를 처리하려면 코드를 다음과 같이 수정할 수 있습니다.
@echo off
setlocal EnableDelayedExpansion
set buildlog=test.txt
set import=false
for /F "tokens=*" %%A in (%buildlog%) do (
for /F "tokens=1" %%B in ("%%A") do (
if /i "%%B"=="Import:" (
set import=true
)
if /i "%%B"=="View:" (
set import=false
)
if !import!==true (
if not "%%B"=="Import:" (
for /F "tokens=1" %%C in ("%%A") do (
echo %%C
)
)
)
)
)
이렇게 추가된 For 루프는 전체 라인을 확인하는 대신 라인에서 첫 번째 토큰을 가져와 "View:" 또는 "Import:"인지 확인합니다. 검사를 수행하기 위해 라인에서 처음으로 만나는 공백 이후의 모든 항목을 효과적으로 무시합니다.
답변2
@echo off
for /F "usebackq tokens=1" %%A in ("devel.p4inc") do (
Set temp=False
if "%%A" == "View:" Goto Exit
if not "%%A" == "Import:" if not "%%A" == "Version:" echo %%A
)
:Exit
답변3
명령줄:
powershell [string]$f=gc test.txt;$pL=$f.IndexOf('Import:')+7;$pR=$f.IndexOf('View:');$s=$f.Substring($pL,$pR-$pL);$s -split'#head'^|ac result.txt
파워셸:
powershell ./parsefl.ps1
parsfl.ps1
[string]$f=gc test.txt;
$pL=$f.IndexOf('Import:')+'Import:'.Length;$pR=$f.IndexOf('View:');
$s=$f.Substring($pL,$pR-$pL);
$s -split'#head'|ac result.txt