2012-11-03 7 views
0
@echo off 
cd %~dp0 
md .\newfolder 
for /f "usebackq delims=" %%f in ("list.txt") do (
    call set /a add=%%add%%+1 
    call set addx=0000%%add%% 
    call set addx=%%addx:~-3%% 
    call copy "%%f" ".\newfolder\%%addx%%_%%f" 
) 
pause 

간단한 이름 변경 코드를 만들었습니다. 나는 보통 '호출'없이 명령을 사용하지만 여기서는 오류 메시지가 발생합니다. 그게 왜? .. 그리고 % variable % % 변수 %%를 사용할 때, 잘 작동하지 않습니다 .. plz 왜 그런 일이 일어 났는지 .. 마지막 질문 .. 환경 변수 값은 cmd를 종료 할 때까지 저장됩니다. 나는 그걸 어떻게 풀 수 있는지 알고 싶다 .. 고마워.배치 명령의 차이점은 무엇입니까?

답변

1

괄호 안의 블록 내의 모든 코드는 한 번에 처리된다. 퍼센 트를 사용하는 일반적인 변수 확장은 구문 분석시 발생합니다. 따라서 블록 내에서 변수를 설정하면 일반 확장을 사용하여 값에 액세스 할 수 없습니다. 그 이유는 값이 블록을 입력하기 전에 있었던 값이기 때문입니다.

위와 같은 상황이 발생했습니다. 문제를 해결하는 두 가지 고전적인 방법이 있습니다.

1) 수행 한 것처럼 CALL을 사용하여 퍼센트를 두 배로 늘릴 수 있습니다. CALL은 호출 된 라인에 대해 두 번 일반 확장이 발생하기 때문에 전체 블록에 대해 한 번, 그리고 라인이 실행되기 전에 다시 블록의 이전 라인이 실행 된 이후에 문제를 해결합니다. 첫 번째 확장은 두 배의 퍼센트를 단일 퍼센트로 변환하고, 두 번째 확장은 실제로 변수를 확장합니다.

속도가 느리고 CALL이 따옴표가 붙은 ^ 문자와 함께 문제를 일으키기 때문에이 솔루션이 마음에 들지 않습니다. 두 배가됩니다.

동일한 명령에서 여러 개의 CALL을 사용할 수 있습니다. 각 전화는 퍼센트가 두 배가되도록 요구합니다. 그래서 하나의 CALL은 2 퍼센트가 필요하고, 두 CALL은 4 perecents, CALL은 3 퍼센트의 CALL이 필요합니다.

2) 나는 바람직한 확장 된 확장 방법을 사용하는 것이 해결책이라고 생각합니다. 훨씬 빠르며 지연 확장을 사용하면 &, |, >, < 등의 특수 문자를 이스케이프하거나 인용 할 필요가 없습니다. 지연된 확장은 말한 그대로입니다. 변수는 행이 실행되기 직전까지 확장되지 않습니다. 지연된 확장을 사용하려면 먼저 사용하도록 설정해야합니다. 배치 파일 내에서 setlocal enableDelayedExpansion을 사용할 수 있습니다.

지연된 확장에서 발생할 수있는 한 가지 문제점은 !이 포함되어 있고 확장 된 지연 확장이 사용되는 경우 FOR 변수가 손상된다는 것입니다. 이는 보통 루프 내에서 지연된 확장을 켜고 끄는 방법으로 해결할 수 있습니다. 명령 프롬프트에서 HELP SET를 입력하면


, 당신은 코드 블록 내에서 변수를 확장하여 문제의 꽤 좋은 설명을 얻을 것이다, 어떻게 지연 확장을 할 수 있습니다. 설명은 단어의 반쯤 시작하여 Finally, support for delayed environment variable expansion...으로 시작됩니다.


주 - SET/A 계산에서 사용할 때는 변수를 확장 할 필요가 없습니다. SET/A는 실행시 자동으로 값을 확장합니다. 정의되지 않은 변수는 0으로 처리됩니다.

코드에서

, 당신은 단순히 set /a add=add+1

를 사용할 수 있지만 더 간단한 속기 방법이 있습니다 - 당신이 += 연산자를 사용할 수 있습니다 set /a add+=1를.


다음은 CALL을 사용하지 않고 코드를 작성하는 또 다른 방법입니다. 코드는 테스트되지 않았지만 제대로 된 것 같습니다. 이미 값으로 설정 될 수 있기 때문에

@echo off 
setlocal disableDelayedExpansion 
cd "%~dp0" 
md newfolder 
set add=0 
for /f "usebackq eol=: delims=" %%F in ("list.txt") do (
    set /a add+=1 
    set "file=%%F" 
    setlocal enableDelayedExpansion 
    set "addx=00!add!" 
    copy "!file!" "newfolder\!addx:~-3!_!file!" 
    endlocal 
) 
pause 

I 명시 적으로 0-add를 초기화합니다. 정의되지 않았거나 이미 0으로 설정된 경우 초기화가 필요하지 않습니다.

FOR 루프가 파일 이름을 처리하고 있으며 !이 파일 이름 내에서 유효합니다. 그건 내가 루프 내에서 켜거나 확장을 지연 토글 이유 - 나는 %%F을 확장 할 때 나는이 손상 될 !와 파일 이름을 원하지 않는다. 파일 이름은 ;으로 시작할 수도 있습니다 (가능성은 낮음). 그렇다면 기본 EOL 문자가 ;이므로 FOR는 해당 파일을 건너 뜁니다. 파일은 :으로 시작될 수 없으므로 대신 EOL을 :으로 설정하는 것이 좋습니다.

배치 파일을 완료 한 후 환경 변수 정의가 지속되지 않도록 SETLOCAL을 맨 위에 놓습니다.

+0

천재 덕분입니다 – dskim

+0

어디에서 더 자세한 정보를 얻을 수 있습니까? 나는 초급이다. 영어에 익숙하지 않아서 이해하기 힘들다. – dskim

관련 문제