Chemin de fichier Windows converti en chemin de fichier Linux

13

J'ai un chemin Windows dans une variable bash sous forme de chaîne:

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

J'essaie de convertir ce chemin en un chemin Linux commençant par /c/Users....

Ma tentative

Les oeuvres suivantes:

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

Problème

Ici, je l'ai fait pour une chaîne qui contient le chemin de fichier. La raison pour laquelle je pose cette question est que je dois convertir 20 chaînes de ce type dans un script bash dans Ubuntu 16.04 et chaque fois que je fais cela, je dois écrire 2 lignes par conversion - cela prend beaucoup de place!

Question

Existe-t-il un moyen de combiner les 2 commandes

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

en une seule commande?

edesz
la source
1
Utilisez une boucle for (et peut-être un tableau). Citez également vos variables.
wjandrea
Merci. Pourriez-vous montrer un exemple de la façon de procéder dans une boucle ou un tableau?
edesz

Réponses:

17

Il y aurait un moyen de faire les deux remplacements à la fois en utilisant sed, mais ce n'est pas nécessaire.

Voici comment je résoudrais ce problème:

  1. Mettre les noms de fichiers dans un tableau
  2. Itérer sur le tableau

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

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

Si vous souhaitez placer la sortie dans un tableau au lieu d'imprimer, remplacez la echoligne par une affectation:

  filenames_out+=( "$f" )
wjandrea
la source
Ok. Mais si j'avais 2 fichiers f1et f2comment cela fonctionnerait-il? Je veux dire, comment puis-je réattribuer les nouveaux noms de fichiers au tableau en remplaçant les anciens?
edesz
@WR les place dans un nouveau tableau et les utilise.
muru
@WR Ajouté cela dans la réponse
wjandrea
1
Je recommanderais de faire un nouveau tableau, par souci de clarté.
wjandrea
9

Si c'est quelque chose que vous voulez faire plusieurs fois, alors pourquoi ne pas créer une petite fonction shell?

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
tournevis
la source
Ce n'est pas une mauvaise idée. Cependant, il ne semble pas donner /c/Users...- au lieu de cela, il donne C:\Users\....
edesz
@WR excuses - erreur de copier-coller. Veuillez l'essayer maintenant.
steeldriver
1
Merci, j'utilise cdw () { f="${1/D://d}"; cd "/mnt${f//\\//}"; }dans le sous-système Windows pour Linux, fonctionne comme un charme!
week
2

Vous seriez en mesure de réaliser cela en une seule ligne en utilisant sed

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

Notez que les deux modèles doivent néanmoins rester séparés car les correspondances sont remplacées par des substitutions différentes.

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

Cette question est-elle toujours ouverte à de nouvelles suggestions? Si oui, cela vous aiderait-il?

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

Oh, et au cas où le C doit être converti en minuscules:

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

En résumé:

$ 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

la source
Quelle est la raison de l'utilisation '^C'?
edesz
1
^ signifie le début de la ligne, sinon toutes les occurrences de C deviendront minuscules ... s'il y en a
Je dois ajouter que les autres suggestions fonctionnent également. Beaucoup de commandes Unix peuvent faire le même travail, donc c'est à vous de choisir le style de solution que vous préférez utiliser.
Je n'avais pas demandé plus tôt ^ ce qui a été utilisé dans d'autres réponses ici aussi. Merci pour la réponse et l'explication.
edesz