Чи є спосіб отримати оболонку cmd для розширення магістральних шляхів?


37

Іноді неможливість розширення магістральних каналів для розширення контурів у програмі cmd може бути незручністю. Мені довелося передати програму 100 файлів у каталозі, і я не зміг набрати * .ext. Натомість я використав 'ls' mingw, щоб скинути список у файл, потім замінив нові рядки пробілами, скопіював та вставив у cmd. Досить кошмар.

Я підозрюю, що відповідь буде "ні", але хтось займався цим чи придумав який-небудь спосіб зробити це простіше?


2
Чи думали ви замість цього використовувати щось на кшталт Powershell?

I suspect the answer will be no, but has anyone dealt with this or come up with any way to make this easier? Насправді, у мене виникає протилежна проблема, я намагаюся знайти спосіб, як дозволити команду-інтерпретатору трактувати його список як рядки та не допускати їх повторного введення в якості символів. Наприклад, for %i in (foobar baz really?) do @echo %iрозглядатиме останній елемент ( really?) в якості імені файлу шаблону, і пропустити його , якщо немає файлів з ім'ям really1, reallyzі т.д. ☹
Synetech

1
@Synetech - ?не є юридичним символом для імен файлів у файловій системі Windows. Персонаж може трактуватися лише як підстановка. Див. Іменування файлів, шляхів та просторів імен на MSDN та використання символів підстановки у TechNet.
jww

Відповіді:


18

DOS, а отже, Windows ' cmd.exe, ніколи не підтримували розширення шаблону за допомогою оболонки. Розширення завжди було залежно від програми.

Це означає, що вам завжди доведеться знайти інший маршрут, якщо ви використовуєте додаток, який не підтримує розширення. Ти міг:

  • Використовуйте цикл FOR для запуску деяких команд проти всіх файлів, які вас цікавлять
  • Використовуйте dir /b > list.txtвикористовувати dirкоманду для розширення і помістити список файлів в текстовий файл (ви можете потім використовувати що - щось на зразок формули Excel , якщо ви дійсно відчайдушним , щоб отримати список команд , щоб вставити в cmd, або ви можете використовувати Excel перенести клітинки, щоб усі імена файлів знаходились на одній лінії.)

Він пояснив, що було б кошмаром виводити результати dir у файл і обробляти фільтрування та копіювання вручну. Відповідь wmz і, звичайно, моя працюватиме без фільтрування вмісту файлів вручну.
wullxz

1
@wullxz: Можливо, але для того, хто незнайомий з Powershell, який хоче це зробити як разовий, це може бути значно швидше - і ідея цього веб-сайту полягає у наданні корисних рішень людям усіх рівнів кваліфікації, щоб звертатися до цього та зараз майбутнє, так що насправді немає необхідності відмовляти мені, бо ти вважаєш, що моя відповідь не така хороша, як твоя.
Malvineous

1
"DOS, а отже, Windows 'cmd.exe, ніколи не підтримував розширення шаблону оболонками." - Неправда за даними Microsoft. Див. Розділ Використання символів підстановки на TechNet. (Але я думаю, ви маєте рацію на практиці: о. Інакше я б тут не намагався з'ясувати, чому файли не відповідають)
jww

1
@jww: Посилання, яке ви розмістили, пояснює стандартне використання символів підстановки, але я не бачу жодної згадки про те, як вони розширюються оболонкою. На відміну від UNIX (а пізніше Linux та Mac), Microsoft залишила розширення підстановки до кожного окремого додатка для реалізації, передаючи параметри командного рядка через "є".
Malvineous

1
Команда DOS 'dir Filespec / b' працює дуже добре, оскільки створює список файлів, по одному на рядок. За допомогою додаткового перемикача '/ s' назви файлів є повністю кваліфікованими (абсолютними) і їх можна легко передати через цикл for для будь-якої іншої програми командного рядка, яка приймає ім'я файлу. Це найкраще, що ми можемо зробити, оскільки Windows не має належної функції глобалізації.
Девід А. Грей

9

Просто використовуйте Powershell, який попередньо встановлений на Windows 7. Powershell здатний виконувати команди cmd і розуміє підстановку в будь-якому місці шляху.

Щоб запустити Powershell, просто введіть у вікні пошуку меню запуску "powerhell" і натисніть клавішу Enter.


Якщо програма очікує, що рядок із усіма іменами файлів у ній, це правильний сценарій:

$delimiter = " "
[string]$files = $nothing ; ls *.txt | % { $files += $_.fullname + $delimiter } ; application.exe $files

Змініть $delimiter = " "на, $delimiter = ","якщо ваша програма очікує списку імен файлів, розділених комами.

Пояснення коду:

  • [string]$files = $nothing - створює порожню змінну типу string
  • ; - це роздільник для декількох команд, а не конвеєр!
  • ls *.txt | % { $files += $_.fullname + $delimiter } - отримує список усіх текстових файлів і створює рядок із усіма іменами файлів, розділеними роздільником
  • application.exe $files - викликає програму та передає їй список файлів

Ви навіть можете шукати шаблон файлу рекурсивно, додаючи -recurseдо ls *.txtцього, щоб повний код виглядав так:

$delimiter = " "
[string]$files = $nothing ; ls *.txt -recurse | % { $files += $_.fullname + $delimiter } ; application.exe $files

Edit:
Для того, щоб уникнути роздратування, lsі dirє псевдоніми Get-ChildItemі %є псевдонімом ForEach-Object. Я зберігаю свій код із псевдонімами, які використовуються, оскільки він коротший.

EDIT 2018/04/25:
Ще в 2012 році я був досить новим у PowerShell. Звичайно, існує простіший спосіб, хоча це не так просто, як можливість Unix / linux для глобального розширення:

app.exe $(ls *.txt | % {$_.FullName})

Пояснення:

  • $ () спочатку оцінить вираз усередині і замінить себе виведенням цього виразу (так, як це роблять задні посилання в баші)
  • ls *.txt отримує FileInfo об’єкти всіх файлів, які відповідають глобальній *.txt
  • оскільки PowerShell орієнтована на об'єкт, ми повинні вивести повне ім'я кожного об'єкта FileInfo. Просто називання атрибута / властивості в PowerShell видає його за замовчуванням. % { $_.FileName }робить це для нас. %петлі над усіма елементами, поверненими lsі видає кожен об'єкт FileName.

2
Хоча PS, безумовно, здатний виконати запит, і порада ознайомитися з ним звучить - це не так просто, як ви пропонуєте. Запуск start notepad++ *.txt(з метою відкрити всі TextFiles - використовується Notepad ++ , як це робить обробляти кілька імен) не доб'єшся
WMZ

1
Ви можете це вирішити dir *.txt | % { notepad++.exe $_ }. Я спробував це за допомогою простого блокнота, оскільки у мене немає блокнота ++, і він працював. Команда отримує список усіх txt-файлів у поточній папці, передає список наступній команді, яка проходить цикл через список та виконує блокнот ++ із назвою файлу як параметром.
wullxz

так, але це не рівнозначно. Подумайте, grep "a b c"щоб знайти будь-який із перелічених рядків, де "ab c" буде розширений список
wmz

5
Запуск команди зі списком елементів у якості параметра не еквівалентний виконанню команди кілька разів із кожним елементом зі списку як параметром. Інший приклад: copy a+b+c resultі copy a result copy b result copy c result. (і греп як утиліта існує в PS, так і називається select-string)
wmz

1
прихильно, до речі, шкода, що ОП не підозрює пояснювати ...
wmz

8

Це дасть вам список, а також помістить його в змінну з назвою expanded_list. Помістіть його в пакетний файл і запустіть myBatchFile name myPattern. Прикладіть шаблон до лапок, якщо він містить пробіли. Збігаються файли, немає рішень. Запуск без параметрів відповідає всім.

@echo off
set expanded_list=
for /f "tokens=*" %%F in ('dir /b /a:-d "%~1"') do call set expanded_list=%%expanded_list%% "%%F"

echo expanded_list is: 
echo %expanded_list%

Потім можна запустити команду за допомогою my_command_exec %expanded_list%

УВАГА! Максимальний розмір змінної cmd - 8191 символ (XP далі), тому можливо її переповнення! Ви не можете розраховувати, що утиліта завжди надасть вам повний список. З іншого боку, максимальна довжина рядка cmd також становить 8191, так що ви все одно не зможете виконати її.


Зверніть увагу, якщо аргументи не вказані, тоді розширений список буде встановлений для всіх файлів у поточній директорії, які можуть бути, а можуть і не бути потрібними, тому, можливо, потрібно додати перевірку на відсутність аргументів (наприклад, якщо "% 1" == "" ...)
JasonM1

3

Це працює в cmd.exe

dir /b *.ext

або

echo | dir /b *.ext

Це працює лише для імені файлу, а не для будь-якої частини шляху. Наприклад dir /b TortoiseSVN\bin\sv*.exeпокаже svn.exeі svnadmin.exe. Але dir /b TortoiseSVN\bi*\svn.exeпоказує синтаксичну помилку.
styfle

1
перевірити dir /s /b. Це дає вам повний шлях.
WesternGun

3

Зауважте, це в коментарі до плакатів в окремому потоці user619818 та styfle)

DIR може і дозволяє дозволяти шукати всі підкаталоги для файлів, що відповідають певному типу.

Примітка. Корінний каталог, щоб перевірити, у яких підкаталогах лежать, вважається "C: \ Моя програма \ Root \", оскільки автор не вказав ім'я шляху, під яким розташовані ці каталоги

DIR /B /S "C:\My Program\Root\*.ext"

це дасть повний шлях до файлів та назви файлів вихідних файлів.

якщо ви хочете лише імена файлів, вам доведеться зробити наступне

FOR /F "Tokens=*" %A IN ('DIR /B /S "C:\My Program\Root\*.ext"') DO @( Echo.%~nxA )

тож припускаючи, що ви хочете перемістити всі ці файли з "C: \ Моєї програми \ Root \ Підкаталогами \ *. ext" до "D: \ Single Folder \ *. ext", ви просто зробите це:

FOR /F "Tokens=*" %A IN ('DIR /B /S "C:\My Program\Root\*.ext"') DO @( MOVE "%~A" "D:\Singlefolder\%~nxA" /Y )

Сподіваюся, що допоможе іншим у майбутньому. :)


1

Це старе, але з підсистемою Linux для Windows, зараз досить часто базуватись у вашому PATH. Якщо це так, то це може зробити для вас трюк:

bash -c 'cat *.txt'

зауважте, що одиночні лапки не є особливими для cmd Windows , тому, якщо запустити вищевказану команду з cmd, вона не працюватиме. І це стосується також систем з Cygwin або інших баш-середовищ
phuclv
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.