Windows filepath dikonversi ke Linux filepath

13

Saya memiliki jalur Windows di variabel bash sebagai string:

file='C:\Users\abcd\Downloads\testingFile.log'

Saya mencoba mengubah jalur ini menjadi jalur Linux yang dimulai dengan /c/Users....

Usaha saya

Karya-karya berikut:

file=${file/C://c}
file=${file//\\//}
echo $file
> /c/Users/abcd/Downloads/testingFile.log

Masalah

Di sini, saya telah melakukan ini untuk string yang berisi file path. Alasan saya mengajukan pertanyaan ini adalah bahwa saya harus mengonversi 20 string seperti itu dalam skrip bash di Ubuntu 16.04 dan setiap kali saya melakukan ini, saya harus menulis 2 baris per konversi - ini menghabiskan banyak ruang!

Pertanyaan

Apakah ada cara untuk menggabungkan 2 perintah

file=${file/C://c}
file=${file//\\//}

menjadi satu perintah?

edesz
sumber
1
Gunakan for for (dan mungkin sebuah array). Kutip juga variabel Anda.
wjandrea
Terima kasih. Bisakah Anda menunjukkan contoh bagaimana melakukan ini dalam satu lingkaran atau array?
edesz

Jawaban:

17

Akan ada cara untuk melakukan penggantian keduanya sekaligus menggunakan sed, tetapi itu tidak perlu.

Inilah cara saya mengatasi masalah ini:

  1. Masukkan nama file dalam array
  2. Iterate over array

filenames=(
  'C:\Users\abcd\Downloads\testingFile.log'
  # ... add more here ...
)

for f in "${filenames[@]}"; do
  f="${f/C://c}"
  f="${f//\\//}"
  echo "$f"
done

Jika Anda ingin meletakkan output ke dalam array daripada mencetak, ganti echobaris dengan tugas:

  filenames_out+=( "$f" )
wjandrea
sumber
Oke. Tetapi jika saya memiliki 2 file f1dan f2, bagaimana cara kerjanya? Maksud saya, bagaimana cara menetapkan ulang nama file baru ke array dengan mengganti yang lama?
edesz
@WR menempatkan mereka dalam array baru dan menggunakannya.
muru
@WR Menambahkan itu ke dalam jawaban
wjandrea
1
Saya akan merekomendasikan untuk membuat array baru, demi kejelasan.
wjandrea
9

Jika itu sesuatu yang ingin Anda lakukan berkali-kali, mengapa tidak membuat fungsi shell kecil?

win2lin () { f="${1/C://c}"; printf '%s\n' "${f//\\//}"; }

$ file='C:\Users\abcd\Downloads\testingFile.log'
$ win2lin "$file"
/c/Users/abcd/Downloads/testingFile.log
$ 
$ file='C:\Users\pqrs\Documents\foobar'
$ win2lin "$file"
/c/Users/pqrs/Documents/foobar
Steeldriver
sumber
Itu bukan ide yang buruk. Namun, itu tampaknya tidak memberi /c/Users...- melainkan memberi C:\Users\....
edesz
@WR permintaan maaf - kesalahan salin-tempel. Silakan coba sekarang.
steeldriver
1
Terima kasih, saya menggunakan cdw () { f="${1/D://d}"; cd "/mnt${f//\\//}"; }subsistem Windows untuk Linux, bekerja seperti pesona!
Akhir pekan
2

Anda akan dapat mencapai ini dalam satu baris menggunakan sed

file="$(echo "$file" | sed -r -e 's|^C:|/c|' -e 's|\\|/|g')"

Perhatikan bahwa kedua pola harus tetap terpisah karena pertandingan diganti dengan pergantian yang berbeda.

taifwa
sumber
1
Sinonim:file="$(sed 's|^C:|/c|; s|\\|/|g' <<< "$file")"
wjandrea
1

Apakah pertanyaan ini masih terbuka untuk saran baru? Jika demikian, apakah ini akan membantu Anda?

$ file="/$(echo 'C:\Users\abcd\Downloads\testingFile.log'|tr '\\' '/')"
$ echo $file
/C:/Users/abcd/Downloads/testingFile.log

Oh, dan seandainya C harus dilemparkan ke huruf kecil:

file="/$(echo 'C:\Users\abcd\Downloads\testingFile.log'|tr '^C' 'c'|tr '\\' '/')"

Sebagai gambaran umum:

$ file='C:\Users\abcd\Downloads\testingFile.log'
$ echo $file
C:\Users\abcd\Downloads\testingFile.log
$ file="/$(echo $file|tr '^C' 'c'|tr '\\' '/')"
$ echo $file
/c:/Users/abcd/Downloads/testingFile.log

sumber
Apa alasan penggunaannya '^C'?
edesz
1
^ berarti mulai dari baris, jika tidak semua kejadian C akan menjadi huruf kecil ... harus ada
Saya harus menambahkan bahwa saran lain juga berfungsi. Banyak perintah Unix dapat melakukan pekerjaan yang sama, jadi terserah Anda apa jenis solusi yang Anda suka gunakan.
Saya belum bertanya sebelumnya tentang ^yang telah digunakan dalam beberapa jawaban lain di sini juga. Terima kasih atas jawabannya dan penjelasannya.
edesz