มีวิธีการรับ windows cmd shell เพื่อขยายเส้นทางสัญลักษณ์?


37

บางครั้งการที่ cmd shell ไม่สามารถขยายเส้นทาง wildcard อาจเป็นความไม่สะดวก ฉันต้องส่ง 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? ที่จริงแล้วฉันมีปัญหาตรงข้ามฉันพยายามคิดหาวิธีที่จะให้ command-interpreter ปฏิบัติต่อรายการของมันเป็นสตริงและป้องกันไม่ให้มันเข้ามาแทนที่ wildcard ยกตัวอย่างเช่นfor %i in (foobar baz really?) do @echo %iจะปฏิบัติต่อรายการสุดท้าย ( really?) เป็นสัญลักษณ์แทนชื่อไฟล์และข้ามถ้ามีไฟล์ไม่มีชื่อreally1, reallyzฯลฯ ☹
Synetech

1
@Synetech - ?ไม่ใช่ตัวอักษรที่ถูกกฎหมายสำหรับชื่อไฟล์ในระบบไฟล์ Windows อักขระสามารถตีความได้ว่าเป็นอักขระตัวแทนเท่านั้น ดูการตั้งชื่อไฟล์เส้นทางและเนมสเปซบน MSDN และการใช้อักขระตัวแทนใน TechNet
jww

คำตอบ:


18

DOS และด้วยเหตุนี้ Windows ' cmd.exeจึงไม่เคยรองรับการขยายด้วย wildcard โดยเชลล์ มันขึ้นอยู่กับแอปพลิเคชันเพื่อทำการขยาย

ซึ่งหมายความว่าคุณจะต้องค้นหาเส้นทางอื่นเสมอหากคุณใช้แอพพลิเคชั่นที่ไม่รองรับการขยายตัว คุณสามารถ:

  • ใช้การวนรอบ FORเพื่อเรียกใช้คำสั่งบางอย่างกับไฟล์ทั้งหมดที่คุณสนใจ
  • ใช้dir /b > list.txtเพื่อใช้dirคำสั่งเพื่อทำการขยายและวางรายการไฟล์ลงในไฟล์ข้อความ (จากนั้นคุณสามารถใช้บางอย่างเช่นสูตร Excel หากคุณหมดหวังที่จะสร้างรายการคำสั่งที่จะวางcmdหรือคุณสามารถใช้ Excel เพื่อย้ายเซลล์เพื่อให้ชื่อไฟล์ทั้งหมดอยู่ในบรรทัดเดียวกัน)

เขาอธิบายว่ามันจะเป็นฝันร้ายที่จะให้ผลลัพธ์ผลลัพธ์ของ dir ลงในไฟล์และกระบวนการกรองและคัดลอกด้วยตนเอง คำตอบของ wmz และของฉันแน่นอนจะทำงานโดยไม่ต้องกรองเนื้อหาไฟล์ด้วยตนเอง
wullxz

1
@wullxz: บางที แต่สำหรับบางคนที่ไม่คุ้นเคยกับ Powershell ที่ต้องการทำสิ่งนี้แบบครั้งเดียวมันอาจเร็วขึ้นมาก - และแนวคิดเบื้องหลังไซต์นี้คือการจัดหาโซลูชั่นที่มีประโยชน์สำหรับคนทุกระดับทักษะในการอ้างถึงตอนนี้และใน อนาคตดังนั้นไม่จำเป็นต้องบอกฉันเพราะคุณคิดว่าคำตอบของฉันไม่ดีเท่าของคุณ
Malvineous

1
"DOS และ cmd.exe ของ Windows ทำให้เชลล์ไม่รองรับส่วนขยายของ wildcard" - ไม่เป็นความจริงตาม Microsoft ดูที่การใช้อักขระตัวแทนใน TechNet (แต่ฉันคิดว่าคุณถูกต้องในทางปฏิบัติ: o มิฉะนั้นฉันจะไม่พยายามที่จะคิดออกว่าทำไมไฟล์ไม่ตรง)
jww

1
@jww: ลิงก์ที่คุณโพสต์อธิบายถึงการใช้อักขระ wildcard มาตรฐาน แต่ฉันไม่เห็นว่ามีการขยายโดยเชลล์ แตกต่างจาก UNIX (และต่อมา Linux และ Mac) Microsoft ออกจาก wildcard ส่วนขยายไปยังแต่ละแอปพลิเคชันแต่ละตัวเพื่อนำไปใช้ผ่านพารามิเตอร์บรรทัดคำสั่งผ่านตามที่เป็นอยู่
Malvineous

1
คำสั่ง DOS 'dir Filespec / b' ทำงานได้ดีเพราะมันสร้างรายการไฟล์หนึ่งรายการต่อบรรทัด ด้วยสวิตช์เพิ่มเติม '/ s' ชื่อไฟล์จะผ่านการรับรองอย่างสมบูรณ์ (สัมบูรณ์) และสามารถป้อนผ่านลูปสำหรับโปรแกรมบรรทัดคำสั่งอื่น ๆ ที่ใช้ชื่อไฟล์ได้อย่างง่ายดาย เป็นสิ่งที่ดีที่สุดที่เราสามารถทำได้เนื่องจาก Windows ไม่มีคุณสมบัติที่เหมาะอย่างยิ่ง
David A. Gray

9

เพียงใช้ Powershell ซึ่งติดตั้งไว้แล้วใน Windows 7 Powershell สามารถเรียกใช้คำสั่ง cmd และเข้าใจสัญลักษณ์แทนได้ทุกที่ในเส้นทาง

ในการเริ่ม Powershell เพียงแค่พิมพ์ "powershell" ในช่องค้นหาเมนูเริ่มและกด 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

แก้ไข:
เพื่อหลีกเลี่ยงการระคายเคืองlsและdirเป็นนามแฝงของGet-ChildItemและเป็นนามแฝงที่จะ% ForEach-Objectฉันใช้โค้ดแทนด้วยนามแฝงเพราะสั้นกว่า

แก้ไข 2018/04/25:
ย้อนกลับไปในปี 2555 ฉันค่อนข้างใหม่กับ PowerShell แน่นอนว่ามีวิธีที่ง่ายกว่าแม้ว่ามันจะไม่ง่ายเท่าความสามารถในการขยายแบบกลมของยูนิกซ์ / ลินุกซ์:

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

คำอธิบาย:

  • $ () จะประเมินค่านิพจน์ภายในก่อนและจะแทนที่ตัวเองด้วยเอาต์พุตของนิพจน์นั้น (เหมือนกับ backticks ที่ทำใน bash)
  • ls *.txt รับวัตถุ FileInfo ของไฟล์ทั้งหมดที่ตรงกับ glob *.txt
  • เนื่องจาก PowerShell เป็นวัตถุที่มุ่งเน้นเราต้องส่งออกชื่อเต็มของแต่ละวัตถุ FileInfo เพียงตั้งชื่อแอตทริบิวต์ / คุณสมบัติใน PowerShell ให้ผลลัพธ์ตามค่าเริ่มต้น % { $_.FileName }ทำเพื่อเรา %วนซ้ำองค์ประกอบทั้งหมดที่ส่งกลับโดยlsและส่งออกแต่ละวัตถุ FileName

2
Alhough PS นั้นสามารถตอบสนองความต้องการได้อย่างแท้จริงและคำแนะนำในการทำความคุ้นเคยกับเสียง - มันไม่ง่ายอย่างที่คุณแนะนำ เล่นstart notepad++ *.txt(ด้วยความตั้งใจที่จะเปิด textfiles ทั้งหมด - Notepad ++ ที่ใช้ในขณะที่มันไม่จัดการหลายชื่อ) จะได้รับคุณไม่มีที่ไหนเลย
wmz

1
dir *.txt | % { notepad++.exe $_ }คุณสามารถแก้ปัญหาที่มี ฉันลองใช้แผ่นจดบันทึกที่เรียบง่ายเพราะฉันไม่มีแผ่นจดบันทึก ++ และทำงานได้ คำสั่งได้รับรายการของไฟล์ txt ทั้งหมดในไดเรกทอรีปัจจุบันส่งผ่านรายการไปยังคำสั่งถัดไปซึ่งวนรอบรายการและดำเนินการ notepad ++ ด้วยชื่อไฟล์เป็นพารามิเตอร์
wullxz

ใช่ แต่นี่ไม่เทียบเท่ากัน คิดเกี่ยวกับการgrep "a b c"ที่จะหาใด ๆของสตริงที่ระบุไว้ที่ไหน "AB C" จะได้รับการขยายรายการ
wmz

5
การรันคำสั่งด้วยรายการไอเท็มเนื่องจากพารามิเตอร์ไม่เทียบเท่ากับการรันคำสั่งหลายครั้งกับแต่ละอิลิเมนต์จากรายการเป็นพารามิเตอร์ อีกตัวอย่างหนึ่ง: และcopy a+b+c result copy a result copy b result copy c result(และ grep เช่นยูทิลิตี้มีอยู่ใน PS, มันถูกเรียกselect-string)
wmz

1
upvoted, btw มันน่าเสียดายที่ OP ไม่สนใจที่จะพูดสอดในเพื่ออธิบาย ...
wmz

8

expanded_listซึ่งจะทำให้คุณรายการและยังใส่ไว้ในตัวแปรชื่อ myBatchFile name myPatternวางไว้ในแฟ้มชุดและทำงานด้วย ล้อมรอบรูปแบบด้วยเครื่องหมายคำพูดหากมีช่องว่าง ตรงกับไฟล์ไม่มี dirs เรียกใช้โดยไม่มีพารามิเตอร์ที่ตรงกับทั้งหมด

@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 ดังนั้นคุณจะไม่สามารถดำเนินการได้


หมายเหตุหากไม่มีการระบุอาร์กิวเมนต์จะมีการตั้งค่า expand_list เป็นไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันซึ่งอาจหรืออาจไม่ใช่สิ่งที่ต้องการดังนั้นอาจต้องการเพิ่มการตรวจสอบเพื่อหาอาร์กิวเมนต์ไม่ (เช่นถ้า "% 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แสดงข้อผิดพลาดทางไวยากรณ์
สไตล์

1
dir /s /bตรวจสอบ สิ่งนี้ให้เส้นทางที่สมบูรณ์แก่คุณ
WesternGun

3

หมายเหตุนี่คือในความคิดเห็นที่โพสต์ในด้ายแยก user619818 และสไตล์)

DIR สามารถและอนุญาตให้ค้นหาไฟล์ย่อยทั้งหมดสำหรับไฟล์ที่ตรงกับประเภทเฉพาะ

หมายเหตุ: ไดเรกทอรีรากเพื่อตรวจสอบว่าไดเรกทอรีย่อยทั้งหมดอยู่ภายใต้จะถือว่าเป็น "C: \ My Program \ 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: \ My Program \ Root \ Sub Directories \ *. ext" เป็น "D: \ Singlefolder \ *. ext" คุณทำได้ดังนี้:

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

หวังว่าจะช่วยคนอื่นในอนาคต :)


1

นี่เป็นรุ่นเก่า แต่ด้วยระบบย่อยของลินุกซ์สำหรับ windows มันเป็นเรื่องธรรมดาที่จะมีการทุบตีใน PATH ของคุณตอนนี้ หากเป็นเช่นนั้นนี่อาจเป็นเคล็ดลับสำหรับคุณ:

bash -c 'cat *.txt'

โปรดทราบว่าคำพูดเดียวไม่ได้พิเศษใน Windows cmdดังนั้นถ้าคุณเรียกใช้คำสั่งดังกล่าวจาก cmd มันจะไม่ทำงาน และสิ่งนี้ยังนำไปใช้กับระบบที่มี Cygwin หรือสภาพแวดล้อมทุบตีอื่น ๆ
phuclv
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.