Linux dosyayoluna dönüştürülen Windows dosyayolu


13

Dize olarak bash değişkeninde bir Windows yolu var:

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

Bu yolu ile başlayan bir Linux yoluna dönüştürmeye çalışıyorum /c/Users....

Girişimi

Aşağıdaki işler:

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

Sorun

Burada, bunu dosya yolunu içeren bir dize için yaptım. Bu soruyu sormamın nedeni, Ubuntu 16.04'teki bir bash betiğinde 20 tane dizeyi dönüştürmek zorunda olduğum ve bunu her yaptığımda dönüşüm başına 2 satır yazmak zorundayım - çok fazla yer kaplıyor!

Soru

2 komutu birleştirmenin bir yolu var mı

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

bir komuta?


1
For döngüsü (ve belki de bir dizi) kullanın. Ayrıca değişkenlerinizi alıntılayın.
wjandrea

Teşekkürler. Bunu bir döngüde veya dizide nasıl yapacağınıza ilişkin bir örnek gösterebilir misiniz?
edesz

Yanıtlar:


17

Her iki değiştirme işlemini aynı anda kullanmanın bir yolu olurdu sed, ancak gerekli değildir.

Bu sorunu şu şekilde çözerdim:

  1. Dosya adlarını diziye koy
  2. Dizi üzerinden yineleme

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

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

Çıktıyı yazdırmak yerine bir diziye koymak istiyorsanız, echosatırı bir atamayla değiştirin:

  filenames_out+=( "$f" )

Ben 2 dosya olsaydı Ok.But f1ve f2Nasıl olacak ki? Yani, eskilerini değiştirerek diziye yeni dosya adlarını nasıl yeniden atarım?
edesz

@WR onları yeni bir diziye koydu ve kullan.
muru

@WR Cevaba ekledi
wjandrea

1
Açıklık uğruna yeni bir dizi oluşturmanızı tavsiye ederim.
wjandrea

9

Birçok kez yapmak istediğiniz bir şeyse, neden küçük bir kabuk işlevi oluşturmuyorsunuz?

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

Bu kötü bir fikir değil. Ancak, vermek gibi görünmüyor /c/Users...- bunun yerine veriyor C:\Users\....
edesz

@WR özür - kopyala-yapıştır hatası. Lütfen şimdi deneyin.
steeldriver

1
Teşekkürler, cdw () { f="${1/D://d}"; cd "/mnt${f//\\//}"; }Linux için Windows alt sisteminde kullanıyorum , bir cazibe gibi çalışıyor!
Hafta Sonu

2

Sed kullanarak bir satırda bunu başarabilirsiniz

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

Bununla birlikte, iki patern farklı kalmalıdır çünkü maçlar farklı ikamelerle değiştirilir.


1
Eşanlamlı:file="$(sed 's|^C:|/c|; s|\\|/|g' <<< "$file")"
wjandrea

1

Bu soru hala yeni önerilere açık mı? Eğer öyleyse, bu size yardımcı olur mu?

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

Oh, ve C'nin küçük harfe dökülmesi gerekiyorsa:

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

Genel olarak:

$ 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

Kullanmanın nedeni nedir '^C'?
edesz

1
^ satır başlangıcı anlamına gelir, aksi takdirde C'nin tüm oluşumları küçük harf olur ... varsa

Diğer önerilerin de işe yaradığını eklemeliyim. Birçok Unix komutu aynı işi yapabilir, bu nedenle hangi çözümü kullanmayı tercih edersiniz.

Daha önce ^buradaki diğer bazı cevaplarda da kullanıldığını sormamıştım . Cevabınız ve açıklama için teşekkürler.
edesz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.