Пакетный файл Windows - удаление ведущих символов - PullRequest
0 голосов
/ 04 декабря 2018

У меня есть пакетный файл, который копирует некоторые локальные файлы в область хранения Google с помощью инструмента gsutil.Утилита gsutil создает хороший файл журнала, в котором отображаются сведения о загруженных файлах, а также, в порядке ли это или нет.

Source,Destination,Start,End,Md5,UploadId,Source Size,Bytes Transferred,Result,Description
file://C:\TEMP\file_1.xlsx,gs://app1/backups/file_1.xlsx,2018-12-04T15:25:48.428000Z,2018-12-04T15:25:48.804000Z,CPHHZfdlt6AePAPz6JO2KQ==,,18753,18753,OK,
file://C:\TEMP\file_2.xlsx,gs://app1/backups/file_2.xlsx,2018-12-04T15:25:48.428000Z,2018-12-04T15:25:48.813000Z,aTKCOQSPVwDycM9+NGO28Q==,,18753,18753,OK,

Я бы хотел

  • проверить результат состояния в столбце 8 (OK или FAIL)
  • Если состояние OK,переместите исходный файл в другую папку (чтобы он не загружался снова).

Проблема заключается в том, что к имени файла источника добавляется "file: //", который я не могу удалитьНапример,

file://C:\TEMP\file_1.xlsx

необходимо заменить на этот

C:\TEMP\file_1.xlsx

Я использую цикл for / f и не уверен, отличается ли манипуляция с переменными %% Aв цикле for / f.

@echo off

rem copy the gsutil log file into a temp file and remove the header row using the 'more' command.
more +1 raw_results.log > .\upload_results.log

rem get the source file name (column 1) and the upload result (OK) from column 8
for /f "tokens=1,8 delims=," %%A in (.\upload_results.log) do (
        echo The source file is %%A , the upload status was %%B 

        set line=%%A
        set line=!line:file://:=! >> output2.txt echo !line!
        echo !line!

)

Вывод выглядит следующим образом.

The source file is file://C:\TEMP\file_1.xlsx , the upload status was OK
The source file is file://C:\TEMP\file_2.xlsx , the upload status was OK

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

%var:~7%

Любые указатели или другой способ сделать это очень ценится.

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Имена файлов и пути могут содержать также один или несколько восклицательных знаков.Строка set line=%%A анализируется командным процессором Windows второй раз перед выполнением с включенным отложенным расширением.См. Как анализирует сценарии интерпретатора команд Windows (CMD.EXE)? Каждый ! внутри строки, назначенной переменной цикла A, в этой строке интерпретируется как начало или конец отложенной расширенной переменной средыссылка.Таким образом, строка переменной цикла A присваивается переменной среды line с нежелательной модификацией, если путь / имя файла содержит один или несколько восклицательных знаков.

По этой причине лучше избегать использования отложенногорасширение.Самое быстрое решение для этой задачи - использовать второй FOR для удаления file:// из строки, присвоенной переменной цикла A.

@echo off
del output2.txt 2>nul
for /F "skip=1 tokens=1,8 delims=," %%A in (upload_results.log) do (
    echo The source file is %%A , the upload status was %%B.
    for /F "tokens=1* delims=/" %%C in ("%%~A") do echo %%D>>output2.txt
)

Еще быстрее было бы без первого echo командная строка внутри цикла:

@echo off
(for /F "skip=1 delims=," %%A in (upload_results.log) do (
    for /F "tokens=1* delims=/" %%B in ("%%~A") do echo %%C
))>output2.txt

Второе решение можно записать также в виде одной командной строки:

@(for /F "skip=1 delims=," %%A in (upload_results.log) do @for /F "tokens=1* delims=/" %%B in ("%%~A") do @echo %%C)>output2.txt

Все решения выполняются следующим образом:

external FOR обрабатывает зашифрованный текст ANSI (фиксированный один байт на символ) или кодированный в UTF-8 (один-четыре байта на символ) file upload_results.log построчно с пропуском первой строки иигнорирование всегда пустых строк и строк, начинающихся с точки с запятой, которые здесь не встречаются.

Строка разбивается при каждом появлении одной или нескольких запятых на подстроки (токены) с присвоением первой строки с разделителями-запятыми указанной переменной циклаA.Первое решение дополнительно назначает восьмую строку с разделителями-запятыми следующей переменной цикла B в соответствии с ASCII-таблицей .

Внутренняя FOR обрабатывает строку присваивается переменной цикла A с использованием / в качестве разделителя строк для присвоения указанной переменной цикла file: и следующей переменной цикла в соответствии с таблицей ASCII остальная часть строки после первой последовательности косых черт, которая является полнойполное имя файла.

Полное полное имя файла выводится с помощью команды echo и добавляется либо непосредственно в файл output2.txt (первое решение), либо сначала в буфер памяти, который, наконец, сразу записывается в файл output2.txt перезаписывает, возможно, уже существующий файл с таким именем в текущем каталоге.

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

  • del /?
  • echo /?
  • for /?

См. Также статью Microsoft о Использование операторов перенаправления команд для объяснения перенаправлений >, >> и 2>nul

0 голосов
/ 05 декабря 2018

Поскольку удаляемая часть кажется фиксированной, проще использовать подстроки.

Также использование for /f "skip=1" позволяет избежать необходимости внешней команды more +1 и другого промежуточного файла.

@echo off & setlocal EnableDelayedExpansion
type NUL>output2.txt
for /f "skip=1 eol=| tokens=1,8 delims=," %%A in (.\upload_results.log) do (
    echo The source file is %%A , the upload status was %%B
    set "line=%%A"
    set "line=!line:~7!"
    echo(!line!>>output2.txt
    echo(!line!
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...