2017년 11월 23일 목요일

배치 파일 팁 - 빈 라인(Empty Line)을 포함하여 텍스트 파일 스캔하기

배치파일 안에서 다른 텍스트 파일의 내용을 열람할 수 있습니다.
텍스트 파일의 내용을 열람하려면 아래와 같이 합니다.

for /f "delims=" %%a in (test.txt) do echo.%%a

이렇게 하면 텍스트 파일내의 라인을 출력해줍니다.
예를들어 입력 테스트 파일이 아래와 같다고 하면


아래와 같이 출력됩니다.

이것의 문제는 입력 텍스트의 빈 줄(Empty Line)이 없어졌다는 거죠
그것 자체를 의도했을 수도 있지만 빈 줄 자체를 그대로 처리해야할 때도 있습니다.
이것을 위해서 위의 배치파일을 아래와 같이 수정합니다.

for /f "delims=" %%a in ('type test.txt') do echo.%%a

이것은 괄호안의 명령이 바뀌었습니다.
작은 따옴표를 사용해서 명령어를 만들고 그 실행결과를 줄단위로 파싱합니다.
이것의 결과는 앞에서와 같습니다.

for 명령어는 이처럼 명령어의 실행결과로 리턴되는 출력값을 줄단위로 처리할 수 있습니다.
자세한것은 for의 도움말을 참고하십시요.

for는 본질적으로 "빈 줄"을 처리할 수 없습니다. 그래서 빈 줄을 빈줄이 아닌것으로 가공합니다.
여러가지 도구를 사용할 수 있겠지만 여기서는 find 명령어를 사용합니다.
find 명령어를 사용해서 다음과 같이 입력하면 아래와 같이 결과가 나옵니다.

find /n /v "" test.txt

실행결과는 아래와 같습니다.

공백라인 앞에 [숫자]가 붙어서 확장되었습니다.
그런데 맨 위줄에 "---------- TEST.TXT"이 붙어 있습니다.
이것을 그대로 for문에 입력해 봅니다.

for /f "delims=" %%a in ('find /n /v "" test.txt') do echo.%%a

이것의 실행결과는 아래와 같이 됩니다.

역시 맨위줄에 "---------- TEST.TXT"이 나타나게 됩니다.
맨 위줄에 나오는 "---------- TEST.TXT"를 제거해야 합니다.
방법은 find 명령어에 직접 파일을 지정하지않고 파이프로 사용하는것입니다.
우선 type 명령어로 파일내용을 열람하고 그것을 파이프를 통해서 find에 전달합니다.

for /f "delims=" %%a in ('type test.txt ^| find /n /v ""') do echo.%%a

이것의 실행결과는 아래와 같습니다.


이제 앞에 붙은 [숫자]를 제거할 차례입니다.
for의 옵션을 이용해서 다음과 같이 바꿉니다.
/f 다음에 "tokens=1* delims=]" 를 추가합니다.
이것의 의미는 구분자를 ] 로 사용하고 첫번째 토큰은 %%a에 나머지 토큰은 %%b에 할당하라는 의미 합니다.
앞선 예제에서 옵션만 추가하면 다음과 같게 될겁니다.

for /f "tokens=1* delims=]" %%a in ('type test.txt ^| find /n /v ""') do echo.%%a

실행하면 아래의 결과를 얻습니다.
이렇게 된 이유는 do 다음문장에 쓰여진 "echo.%%a" 때문입니다.
텍스트 라인의 구분자 ] 로 2개의 토큰을 만들었지만 출력은 첫번째 토큰을 출력한것입니다.
구분자를 ] 로 사용한 이유는 find에서 추가하는 라인번호가 항상 그런 형식을 가지고 있기 때문입니다.
이제 마지막으로 아래와 같이 수정합니다.

for /f "tokens=1* delims=]" %%a in ('type test.txt ^| find /n /v ""') do echo.%%b

그러면 아래와 같이 원하는 결과가 출력됩니다.
이 내용은 구글검색에서 아래의 페이지의 내용을 참고하였습니다.

https://social.technet.microsoft.com/Forums/scriptcenter/en-US/b58ec103-cb79-4257-b212-5163735b695d/using-for-f-to-preserve-blank-lines?forum=ITCG


for /f "tokens=1* delims=]" %%a in ('find /n /v "" ^<test.txt') do @echo/%%b

참고의 내용에서는 파이프 대신 리디랙션을 사용한것이 다릅니다.
또한 "echo.%%b" 대신에 "echo/%%b"를 사용하였는데 이는 텍스트 문장에 포함된 내용이 echo의 리디랙션에 영향을 줄까봐 그렇게 한것으로 생각됩니다.
이 글을 읽으신 분들이 직접 적용해보고 차이점이 무엇인지 알려주셨으면 좋겠습니다.

참고의 내용을 포함하여  글내용을 테스트해 볼 수 있는 배치파일 전체는 아래와 같습니다.

@echo off

echo. Black Sheep Wall> test.txt
echo.>> test.txt
echo. Breathe deep>> test.txt
echo.>> test.txt
echo. Food for thought>> test.txt
echo.>> test.txt
echo. Game over man>> test.txt
echo.>> test.txt
echo. Medieval man>> test.txt
echo.>> test.txt
echo. Modify the phase variance>> test.txt
echo.>> test.txt
echo. Operation CWAL>> test.txt
echo.>> test.txt
echo. Power overwhelming>> test.txt
echo.>> test.txt
echo. Show me the money>> test.txt

echo -- Example 1 -----------
for /f "delims=" %%a in (test.txt) do echo.%%a
echo ------------------------

echo -- Example 2 -----------
for /f "delims=" %%a in ('type test.txt') do echo.%%a
echo ------------------------

echo -- Example 3 -----------
for /f "delims=" %%a in ('find /n /v "" test.txt') do echo.%%a
echo ------------------------

echo -- Example 4 -----------
for /f "delims=" %%a in ('type test.txt ^| find /n /v ""') do echo.%%a
echo ------------------------

echo -- Example 5 -----------
for /f "tokens=1* delims=]" %%a in ('type test.txt ^| find /n /v ""') do echo.%%a
echo ------------------------

echo -- Example 6 -----------
for /f "tokens=1* delims=]" %%a in ('type test.txt ^| find /n /v ""') do echo.%%b
echo ------------------------

echo -- Example 7 -----------
for /f "tokens=1* delims=]" %%a in ('find /n /v "" ^<test.txt') do @echo/%%b
echo ------------------------


댓글 없음:

댓글 쓰기