4

Когда я использую copy *.txt somefolder\ кажется, что система копирует также и все *.txt~ файлы, а это не то, что мне нужно. Подобный же эффект можно увидеть с помощью dir:

C:\Users\Paul\Documents\Programs\Proffy>dir *.txt
 Volume in drive C is Vista
 Volume Serial Number is EC23-AD6B

 Directory of C:\Users\Paul\Documents\Programs\Proffy

29/11/2008  13:54            35,821 COPYING.txt
31/10/2009  21:54             1,644 INSTRUCTIONS.txt
06/06/2009  15:57             1,393 INSTRUCTIONS.txt~
04/01/2009  11:59               116 Notes.txt
19/04/2009  16:53               134 README.txt
04/01/2009  12:42               132 README.txt~
31/10/2009  21:30               197 TODO.txt
31/10/2009  19:10               414 TODO.txt~
               8 File(s)         39,851 bytes
               0 Dir(s)  41,938,862,080 bytes free

C:\Users\Paul\Documents\Programs\Proffy>

Как я могу получить dir и copy чтобы работать только с файлами, которые заканчиваются на .txt а не на .txt~?

6 ответов6

5

Очевидно, что оболочка учитывает как короткое, так и длинное имя для подстановочного знака. Более подробное объяснение можно найти в ответе shf301. Это прискорбно и, вероятно, осталось от Ye Olde Days из DOS, потому что это то, с чем cmd пытается быть совместимым - вроде - в конце концов.

Несколько вариантов здесь:

  1. Используйте forfiles , который имеет другую семантику для расширения по шаблону:

    forfiles /m *.txt /c "cmd /c copy @file foo"
    

    Это доступно по крайней мере на Vista и позже.

  2. Используйте for и проверьте расширение:

    for %a in (*.txt) do @if %~xa==.txt @copy "%i" foo
    

    К сожалению , for также возвращает все файлы с расширением .txt~ При использовании только подстановочные расширения. Вот почему нам нужно проверить расширение во второй раз.

  3. Используйте xcopy . Хотя xcopy имеет ту же семантику для расширения подстановочных знаков, что и оболочка, вы можете дать ей файл с именами, которые следует игнорировать:

    echo .txt~>tmpfile
    xcopy *.txt foo /exclude:tmpfile
    del tmpfile
    
  4. Используйте robocopy . Хотя у robocopy та же семантика для расширения с подстановочными знаками, что и у оболочки, вы можете дать ей список файлов / подстановочных знаков, которые следует игнорировать:

    robocopy . foo *.txt /XF *.txt~
    
  5. Используйте for , dir и findstr в соответствующей комбинации. По сути, это просто отфильтровывает все строки, которые имеют ~ в конце, и работает с остальными. if вариант выше был более элегантным, я думаю.

    for /f "usebackq delims=" %i in (`dir /b *.txt ^| findstr /r "[^~]$"`) do @copy "%i" foo
    
  6. Просто для полноты: PowerShell:

    Copy-Item *.txt foo
    
1

Я не уверен, как остановить dir /copy от сопоставления только * .txt, но я могу объяснить, почему * .txt возвращает то, что он делает; оно соответствует короткому имени файла, которое заканчивается на .txt для всех файлов, выполните команду dir /x * .txt, чтобы увидеть это. Эта проблема возникает для каждого набора расширений, которые начинаются с тех же первых трех символов (например, * .htm будет соответствовать htm, html и даже htmlasdfasdf).

Также почти каждое приложение Windows будет действовать таким образом, потому что API, предоставляемый ОС для поиска файлов, FindFirstFile соответствует длинным именам файлов и коротким именам файлов. Цитировать:

Поиск включает в себя длинные и короткие имена файлов.

Вам нужно будет выполнить какую-то пользовательскую фильтрацию, как предложил ответ Йоханнеса Ресселя.

1

Моим решением было выполнить del *.xyz~ до моей copy *.xyz . Не блестяще, но это работает.

0

Поскольку Джо упомянул полноту, я отмечаю, как упомянуто здесь, что это варьируется в зависимости от того , что команды DIR интерпретатора и COPY команды одного использования. Например, команда DIR команде Take Command и ее команда COPY соответствуют по умолчанию только длинным именам, поэтому такого поведения не возникает. (Соответствие как коротких, так и длинных имен может быть включено для совместимости с командами CMD DIR и COPY .)

0

Существующий ответ покрывал, копируя файлы, только упал, но не перечисляя их.

Вы можете использовать бит архива для обеих целей. Хотя он предназначен для использования с XCOPY 1, он также работает с DIR 2.

шаги:

  1. Убедитесь, что бит архива установлен для всех файлов .txt:

    ATTRIB +A *.txt
    
  2. Удалить бит архива из всех файлов .txt~:

    ATTRIB +A *.txt~
    
  3. Перечислите все файлы .txt для которых установлен бит архивирования:

    DIR /AA *.txt
    

    или скопируйте их в somefolder:

    XCOPY /A *.txt somefolder/
    

1 XCOPY использует ключ /A для исключения всех файлов, для которых не установлен бит архивирования. Это может быть использовано для исключения определенных файлов (например, временных файлов) из ежедневных резервных копий. Параметр /M также удаляет бит архива из файлов, что удобно при копировании файлов на небольшие устройства хранения (например, на дискеты). Кроме того, изменение файлов автоматически устанавливает бит архива, поэтому ключ /M можно использовать для инкрементного резервного копирования.

2 DIR /AA показывает только файлы, для которых установлен атрибут архива.

-1

Вы можете попробовать: скопировать "* .txt"

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .