2017-02-22 7 views
0
@Echo off&SetLocal EnableExtensions EnableDelayedExpansion 
cd "C:\Documents and Settings\John\Desktop\New\Interest\f2" 
Pushd "C:\Documents and Settings\John\Desktop\New\Interest\f2" 
Set Line#=26 
Set /A LOfs=24 -1, Len=34 - LOfs 
For %%A in (*.txt) do For /F "tokens=1* delims=:" %%B in (
    'Findstr /N ".*" "%%A" ^|Findstr "^%Line#%:"' 
) do if %errorlevel% == 0 Set "Line=%%C"&Ren "%%~fA" "!Line:~%LOfs%,%Len%! - %%A!"" 
Popd 

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

Если строка 26 пуста, ничего не делайте и не меняйте имя файла.

Я где-то ошибся и кругом кругом.

Может ли кто-нибудь помочь?

спасибо.

+0

Почему есть два кавычки в конце условия 'do'? Это установит команду ren в значение переменной 'line'. – npocmaka

+1

Какой 'ErrorLevel' вы ожидаете' if% ErrorLevel% == 0' для получения? один из 'findstr'? это не может работать, потому что 'findstr' выполняется' for/F' в новом экземпляре 'cmd'. Кроме того, вам понадобится [замедленное расширение] (http://ss64.com/nt/delayedexpansion.html) для '! ErrorLevel!'; альтернативно, вы можете использовать 'if not ErrorLevel 1'. В любом случае, поскольку вы все равно фильтруете строку # 26, вам, вероятно, вообще не нужен запрос 'if' /' ErrorLevel'. После командной строки 'ren' существует' '' слишком много. Тем не менее вам следует предоставить пример, и вы должны описать, что на самом деле происходит ... – aschipfl

+0

Я думал, что ** если% ErrorLevel% == 0 ** будет если ** Findstr/N ". *" "%% A"^| Findstr "^% Линия #%: ** не была пустой строкой. – jaburmester

ответ

0

Вы не указали, как не работает ваш скрипт, но я вижу некоторые потенциальные проблемы. Я также вижу возможные упрощения.

  • Вы, конечно, не нужны оба CD и PUSHD
  • Я избавилась от числовых переменных и включали число литералов в фактическом коде. Вы можете вернуться к переменным, если хотите.
  • Вам не нужен внешний цикл FOR. FINDSTR может искать несколько файлов при использовании подстановочных знаков в имени файла, а затем он будет содержать имя файла, а затем :. Поэтому, если вы добавите опцию /N, вывод будет иметь форму filename:line#:text. Затем вы можете настроить второй FINDSTR, чтобы возвращать только правильные номера строк.
  • Недостаточно игнорировать пустые строки. Ваше переименование работает только в том случае, если после 23-го символа есть хотя бы один действительный символ имени файла. Имена файлов не могут включать :, *, ?, /, \, <, >, или |. (Возможно, я пропустил некоторые). Я скорректировал FOR /F делимы и поиск FINDSTR для компенсации.
  • Расширение переменной переменной, например %%A, приведет к повреждению значений, если они содержат !, и включено замедленное расширение. ! - допустимый символ в именах файлов. Таким образом, замедленное расширение должно включаться и выключаться внутри цикла.

Я считаю, что следующее будет делать то, что вы хотите. В приведенном ниже коде просто будут эхо команды переименования. Удалите ECHO до ren, как только он даст правильные результаты.

@echo off 
setlocal disableDelayedExpansion 
pushd "C:\Documents and Settings\John\Desktop\New\Interest\f2" 
for /f "tokens=1,3 delims=:*?\/<>|" %%A in (
    'findstr /n "^" "*.txt" ^| findstr "^[^:]*:26:.......................[^:*?\\/<>|]"' 
) do (
    set "old=%%A" 
    set "line=%%B" 
    setlocal enableDelayedExpansion 
    ECHO ren "!old!" "!line:~23,11! - !old!" 
    endlocal 
) 
popd 
+0

Использование vars связано с моим ответом OPs [первый очень похожий вопрос] (http://stackoverflow.com/questions/42278373/). Он не проявлял особых усилий и не получал полного ответа. Вышеприведенный код был взят из моего ответа (и некоторые ошибки добавил), когда я отказался продлить мой ответ на новый вопрос. – LotPings

+0

@LotPings - Интересная история. Благодарю. – dbenham

0

немного другой метод для Daves:

@Echo Off 

Set "SrcDir=%UserProfile%\Desktop\New\Interest\f2" 
Set "Mask=*.txt" 
Set "Line#=26" 
Set "LOfs=23" 
Set "Len=11" 

If /I Not "%CD%"=="%SrcDir%" Pushd "%SrcDir%"2>Nul&&(Set _=T)||Exit/B 

For /F "Tokens=1-2* Delims=:" %%A In ('FindStr/N "^" "%Mask%" 2^>Nul' 
) Do If "%%B"=="%Line#%" If Not "%%~C"=="" (Set "Line=%%C" 
    SetLocal EnableDelayedExpansion 
    If Not "!Line:~%LOfs%,%Len%!"=="" (
     If Not Exist "!Line:~%LOfs%,%Len%! - %%A" (
      Ren "%%A" "!Line:~%LOfs%,%Len%! - %%A")) 
    EndLocal) 

If "_"=="T" PopD 
+0

Может ли кто-нибудь помочь в скрипте Compo? Я хочу передать **! Линия: ~% LOfs%,% Len%! ** для переменной, чтобы проверить, что если текст имеет /, который должен быть заменен пробелом, но когда я говорю ** Установить str = "! Line: ~% LOfs%,% Len%!" **, а затем ** ECHO% str% ** Я получаю выход ** ECHO выключен. **. Если я ** ECHO "! Line: ~% LOfs%,% Len%!" ** Я получаю ожидаемый результат. Вся помощь была оценена. Спасибо – jaburmester

+0

Это будет технический вопрос. Я бы посоветовал вам отметить ответ, который вы предпочитаете как правильный, а затем начать новый вопрос, отвечающий вашим новым требованиям. – Compo

0

Этот метод не требует findstr.exe ни переключения setlocal/endlocal, поэтому он должен работать быстрее. Кроме того, он избегает перепрограммировать любой уже переименованный файл, заменяющий простой for %%A на for /F в сочетании с командой dir.

@Echo off 
SetLocal EnableDelayedExpansion 

cd "C:\Documents and Settings\John\Desktop\New\Interest\f2" 
Set /A Line#=26, LOfs=24 -1, Len=34 - LOfs 

For /F "delims=" %%A in ('dir /A-D /B *.txt') do (

    rem Read the desired line from this file 
    (for /L %%i in (1,1,%Line#%) do set "Line=" & set /P "Line=") < "%%A" 

    if defined Line ECHO Ren "%%~fA" "!Line:~%LOfs%,%Len%! - %%A" 

) 

Заметим также, что, когда этот пакетный файл заканчивается текущий каталог автоматически восстанавливается на текущий один, когда setlocal команда была выполнена, так pushd/popd команды не нужны либо.

+0

Несомненно, вы избегаете отложенного расширения, но оно будет терпеть неудачу, если имя файла содержит '!'. Кроме того, в моих руках решение FINDSTR примерно в 5 раз быстрее обнаруживает 26-ю строку, чем использование FOR/L с помощью SET/P. – dbenham

Смежные вопросы