Chuyển đổi đường dẫn Windows cho Windows Ubuntu Bash


31

Tôi có một tập lệnh bó windows sử dụng Windows Ubuntu Bash. Nó nhận được một đường dẫn Windows đầy đủ dưới dạng đối số và sau đó chuyển đường dẫn đó tới một lệnh trong Ubuntu Bash.

@echo off
bash -lic 'ffmpeg -i "%1" output.avi'

Đây "%1"là đường dẫn Windows đầy đủ, như"C:\some path\file.avi"

Lệnh đưa ra lỗi:

C:some pathfile.avi: Protocol not found

Tôi có thể làm gì để đường dẫn Windows này chuyển đổi thành đường dẫn /mnt/c/some\ path/file.avimà Windows Bash thực sự sẽ hiểu?


Những gì bạn cần là thay thế tất cả các lần xuất hiện C:bằng /mnt/c(cũng có khả năng cho các ký tự ổ đĩa khác), phải không?
kleinfreund

Câu trả lời:


41

Windows Build 17046 [1] chứa wslpathtiện ích mới có thể dịch các đường dẫn từ / sang WSL / Windows. Điều này đã được biết là thiếu tính năng WSL. [2]

Ví dụ sử dụng:

$ echo $0
/bin/bash

$ which wslpath
/bin/wslpath

$ wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'
/mnt/c/aaa/bbb/ccc/foo.zip

Bạn có thể gọi wslpathtừ Powershell trên Windows:

>>> wsl wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'
/mnt/c/aaa/bbb/ccc/foo.zip

wslpath tùy chọn và tham số:

-a    force result to absolute path format
-u    translate from a Windows path to a WSL path (default)
-w    translate from a WSL path to a Windows path
-m    translate from a WSL path to a Windows path, with ‘/’ instead of ‘\\’

1
Đối với Windows cũ hơn, có sẵn tại đây: github.com/laurent22/wslpath
Tinh tinh hiếu chiến

1
posh cần thoát '\', nhưng wsl thì không. ví dụ của bạn $ wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'sẽ là $ wslpath -a 'C:\aaa\bbb\ccc\foo.zip'Nó hoạt động khi thoát, nhưng thoát vô dụng là khó hiểu. Người ta có thể cho rằng nó phải được trốn thoát. Ngoài ra, tôi nghĩ rằng mô tả trên -m, ... with ‘/’ instead of ‘\\’nên có một '\' (Tôi biết đó là bản sao được dán) Nếu bạn làm như vậy wslpath -w /mnt/c/Users, nó không in hai '\'
papo

1
Tôi tin rằng đó wslpathmột phần của câu trả lời, nhưng tôi tin rằng bài đăng này không trả lời một cách chức năng câu hỏi - khi một tệp bó có tên kiểu Windows ( C:\foo\bar\blah) cho tệp dữ liệu, làm thế nào để chạy lệnh WSL tập tin đó?
Scott

@papo Tôi vừa vấp phải một vấn đề với các dấu gạch chéo được sử dụng: nó không nhất quán và phụ thuộc vào cách nó chạy, khi chạy từ powershell, nó chỉ bỏ qua các dấu gạch chéo không được giải mã, khi chạy từ bash, nó chỉ xử lý chúng một cách chính xác bên trong chuỗi.
sukhmel

@sukhmel true, trong wsl (trên đó bash cho windows chạy) và cả trong bảng điều khiển cmd, đặt đường dẫn trong dấu ngoặc đơn hoặc dấu ngoặc kép hoặc thoát dưới dạng \ Việc không thoát khỏi dấu ngoặc kép cung cấp cách thực hiện nhanh: cat `wslpath 'sau đó kéo và thả tập tin vào bàn điều khiển và hoàn thành dòng:'`
papo

5

Tôi đã viết một tập tin bat để làm điều này. Chỉ cần đặt tệp bất cứ nơi nào bạn đang làm việc hoặc thêm nó vào đường dẫn của bạn (hoặc chỉ cần đặt nó lên trên mã của bạn, sẽ dễ dàng làm việc hơn). Hãy nhớ gán "biến" cho đường dẫn tệp của bạn trước (nếu bạn đang sử dụng một tệp riêng, hãy thử sử dụng tham số).

Những gì mã làm:

1) Lấy chữ cái đầu tiên của đường dẫn, đó là ổ đĩa.

2) Xóa hai chữ cái đầu tiên.

3) Thay đổi dấu gạch chéo.

4) Đây là phần khó khăn: vì Linux phân biệt chữ hoa chữ thường, chúng ta cần chuyển đổi ký tự viết hoa thành chữ thường. Làm điều này bằng cách khớp từng cái (cho tôi biết nếu có cách nào tốt hơn). Bạn cũng có thể xóa các ký tự ổ đĩa không cần thiết vì có thể bạn không có quá mười ổ đĩa.

5) Kết hợp mọi thứ để đưa ra chuỗi cuối cùng.

Kết quả:

Đầu vào:

E:\myfiles\app1\data\file.csv

Đầu ra (có dấu ngoặc kép):

"/mnt/e/myfiles/app1/data/file.csv"

Mã như sau:

@echo OFF

set "variable=E:\myfiles\app1\data\file.csv"

set "drive=%variable:~0,1%"

set variable=%variable:~2%
set "variable=%variable:\=/%"

if %drive%==A set "drive=a"
if %drive%==B set "drive=b"
if %drive%==C set "drive=c"
if %drive%==D set "drive=d"
if %drive%==E set "drive=e"
if %drive%==F set "drive=f"
if %drive%==G set "drive=g"
if %drive%==H set "drive=h"
if %drive%==I set "drive=i"
if %drive%==J set "drive=j"
if %drive%==K set "drive=k"
if %drive%==L set "drive=l"
if %drive%==M set "drive=m"
if %drive%==N set "drive=n"
if %drive%==O set "drive=o"
if %drive%==P set "drive=p"
if %drive%==Q set "drive=q"
if %drive%==R set "drive=r"
if %drive%==S set "drive=s"
if %drive%==T set "drive=t"
if %drive%==U set "drive=u"
if %drive%==V set "drive=v"
if %drive%==W set "drive=w"
if %drive%==X set "drive=x"
if %drive%==Y set "drive=y"
if %drive%==Z set "drive=z"

set "variable=/mnt/%drive%%variable%"

echo "%variable%"

@echo ON

Còn ngược lại, chuyển đổi đường dẫn Unix sang đường dẫn Windows trong tập lệnh shell?
JacobTheDev 30/03/2017

@JacobTheDev, bạn sẽ chỉ cần sửa đổi một chút cho điều đó;)
PulseJet


0

Sao lại phức tạp thế?

Thay đổi mục đăng ký

HKEY_CLASSES_ROOT\Applications\bash.exe\shell\open\command

từ

C:\Windows\System32\wsl.exe "%1"

đến

C:\Windows\System32\wsl.exe `wslpath '%1'`

Sử dụng backticks trước wslpath và ở cuối, và sử dụng dấu ngoặc kép đơn (đánh dấu thẳng) vào khoảng% 1.

Làm việc cho tôi.


Có thật không? Điều này giải quyết vấn đề trong câu hỏi, bashđược gọi từ một tệp bó? (Lưu ý rằng, trong ví dụ, đối số đầu tiên của bash là -lic, vì vậy tôi không rõ cách thức wslpath '%1'hoạt động của nó.) Và tại sao bạn lại thay đổi từ dấu ngoặc kép ( "%1") sang dấu ngoặc đơn ( '%1')?
Scott
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.