Как извлечь числа из текстового файла, используя пакетный файл Windows? - PullRequest
1 голос
/ 15 сентября 2009

Мне нужно сделать следующее, используя cmd (командная строка Windows).

У меня есть один файл с именем DDD.CLI026.WK0933.DDDMR45.001.head.

Данные в файле как следующие (в одну длинную строку)

HEAD HEALTHDMD Weekly  DDD.CLI026 Centocor  W200908021012 
TRAIL0101 000000000581 00000CKSUM00000223680

Мне нужно извлечь 581 из 000000000581 и скопируйте его в другой файл, IMS_FILE_to_LND.par, используя командную строку Windows или DOS.

Как мне это сделать?

Ответы [ 2 ]

4 голосов
/ 15 сентября 2009

Ирвин, для входного файла (одна строка) вы можете иметь следующие файлы:

infile.txt (the inputfile on one line):
    HEAD HEALTHDMD Weekly  DDD.CLI026 Centocor  W200908021012
     TRAIL0101 000000000581 00000CKSUM00000223680

pre.txt (the first half of your desired file):
    [WCPIT_BIO_EDW.WF:w_DDDMD_LNDG_IMS_NONRET_SALES]
    $$Cust_RowCount=72648
    $$Sales_RowCount=5235998
    $$OuletChangeLog_RowCount=931

post.txt (the second half of your desired file):
    $$Control_RowCount=4495
    $$Outl_Subcat_RowCount=105
    $$Fac_Subcat_RowCount=149

go.cmd (the command file to create your desired file):
    @echo off
    setlocal enableextensions enabledelayedexpansion
    for /f "tokens=8" %%i in (infile.txt) do (
        set num=%%i
    :loop1
        if "!num!"=="0" goto :skip1
        if not "!num:~0,1!"=="0" goto :skip1
        set num=!num:~1!
        goto :loop1
    :skip1
        type pre.txt >outfile.txt
        echo $$DRM45_RowCount=!num!>>outfile.txt
        type post.txt >>outfile.txt
    )
    endlocal

Создает файл:

outfile.txt:
    [WCPIT_BIO_EDW.WF:w_DDDMD_LNDG_IMS_NONRET_SALES]
    $$Cust_RowCount=72648
    $$Sales_RowCount=5235998
    $$OuletChangeLog_RowCount=931
    $$DRM45_RowCount=581
    $$Control_RowCount=4495
    $$Outl_Subcat_RowCount=105
    $$Fac_Subcat_RowCount=149

что, как я полагаю, вы хотели получить из этой серии вопросов.

В порядке пояснения цикл for обрабатывает вашу одну строку, извлекая поле 8 th (000 ... 00581). Секция пропуска цикла просто удаляет начальные нули до тех пор, пока у вас не останется 0 или действительное число (Windows воспринимает числа с начальными нулями как восьмеричные, что нам здесь не подходит).

После извлечения числа вы просто создаете свой файл из пре- и пост-бита вместе со строкой, которую вы хотите изменить.

Я знаю, это немного больше, чем раннее решение awk, которое я дал, но оно подойдет для Windows без необходимости добавлять стороннее программное обеспечение (которое вы указали, не было вариантом ни в одном из ваших других вопросов). ).

Обновление 1: Вот версия, которая по запросу использует один файл шаблона для создания выходного файла. Файл шаблона должен содержать строки, начинающиеся с "pre:" или "post:", чтобы указывать, должны ли они быть до или после вставляемой строки. Строки без маркера вообще не используются, поэтому вы можете вставить пустые строки или комментарии к своему сердцу. Итак, ваш файл будет:

pre:[WCPIT_BIO_EDW.WF:w_DDDMD_LNDG_IMS_NONRET_SALES]
pre:$$Cust_RowCount=72648
pre:$$Sales_RowCount=5235998
pre:$$OuletChangeLog_RowCount=931

post:$$Control_RowCount=4495
post:$$Outl_Subcat_RowCount=105
post:$$Fac_Subcat_RowCount=149

И это командный скрипт, который даст вам то, что вам нужно. Я просто использовал трюк для временного создания пре- и постфайлов для минимизации необходимых изменений.

@echo off
setlocal enableextensions enabledelayedexpansion
del /q /q pre.txt post.txt >nul: 2>nul:
for /f "delims=" %%j in (template.txt) do (
    set ln=%%j
    if "!ln:~0,4!"=="pre:" echo !ln:~4!>>pre.txt
    if "!ln:~0,5!"=="post:" echo !ln:~5!>>post.txt
)
for /f "tokens=8" %%i in (infile.txt) do (
    set num=%%i
:loop1
    if not "!num!"=="0" (
        if "!num:~0,1!"=="0" (
            set num=!num:~1!
            goto :loop1
        )
    )
)
type pre.txt >outfile.txt
echo $$DRM45_RowCount=!num!>>outfile.txt
type post.txt >>outfile.txt
del /q /q pre.txt post.txt >nul: 2>nul:
endlocal

Выводит:

[WCPIT_BIO_EDW.WF:w_DDDMD_LNDG_IMS_NONRET_SALES]
$$Cust_RowCount=72648
$$Sales_RowCount=5235998
$$OuletChangeLog_RowCount=931
$$DRM45_RowCount=581
$$Control_RowCount=4495
$$Outl_Subcat_RowCount=105
$$Fac_Subcat_RowCount=149

точно так же, как и до / после решения выше, но с вашим новым требованием удовлетворено.

Обновление 2: Если вы можете убедить их пойти на решение Cygwin, это все, что вам нужно:

x=$(expr 0 + $(awk '{print $8}' infile))
sed "s/^\$\$DRM45_RowCount=.*$/\$\$DRM45_RowCount=$x/" cfgfile >cfgfile_new

С cfgfile, содержащий:

[WCPIT_BIO_EDW.WF:w_DDDMD_LNDG_IMS_NONRET_SALES]
$$Cust_RowCount=72648
$$Sales_RowCount=5235998
$$OuletChangeLog_RowCount=931
$$DRM45_RowCount=whatever
$$Control_RowCount=4495
$$Outl_Subcat_RowCount=105
$$Fac_Subcat_RowCount=149

и infile содержащие (короче, но одинаковое количество полей):

HD HLTHDMD Wkly DDD.CLI Cntcr  W200908021012 TRAIL0101 00581 00000CKSUM680

вы получаете следующее cfgfile_new:

[WCPIT_BIO_EDW.WF:w_DDDMD_LNDG_IMS_NONRET_SALES]
$$Cust_RowCount=72648
$$Sales_RowCount=5235998
$$OuletChangeLog_RowCount=931
$$DRM45_RowCount=581
$$Control_RowCount=4495
$$Outl_Subcat_RowCount=105
$$Fac_Subcat_RowCount=149

Вуаля! Намного проще. Не стесняйтесь использовать сценарий cmd и сценарий Cygwin, чтобы убедить свое руководство в том, что они должны использовать лучшие инструменты: -)

0 голосов
/ 15 сентября 2009

Можете ли вы установить Cygwin ? Или использовать Microsoft PowerShell ? Если да, у вас будут гораздо более мощные инструменты (например, регулярные выражения) для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...