Percorso file di Windows convertito in percorso file di Linux


13

Ho un percorso di Windows in una variabile bash come stringa:

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

Sto provando a convertire questo percorso in un percorso Linux a partire da /c/Users....

Il mio tentativo

Le seguenti opere:

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

Problema

Qui, l'ho fatto per una stringa che contiene il percorso del file. Il motivo per cui sto ponendo questa domanda è che devo convertire 20 di queste stringhe in uno script bash in Ubuntu 16.04 e ogni volta che lo faccio devo scrivere 2 righe per conversione - occupa molto spazio!

Domanda

C'è un modo per combinare i 2 comandi

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

in un comando?


1
Usa un ciclo for (e forse un array). Cita anche le tue variabili.
wjandrea,

Grazie. Potresti mostrare un esempio di come eseguire questa operazione in un loop o in un array?
edesz,

Risposte:


17

Ci sarebbe un modo per eseguire entrambe le sostituzioni contemporaneamente sed, ma non è necessario.

Ecco come risolverei questo problema:

  1. Metti i nomi dei file nella matrice
  2. Scorrere su 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

Se si desidera inserire l'output in un array anziché stamparlo, sostituire la echoriga con un'assegnazione:

  filenames_out+=( "$f" )

Ok, ma se avessi 2 file f1e f2come funzionerebbe? Voglio dire, come posso riassegnare i nuovi nomi di file all'array sostituendo quelli vecchi?
edesz,

@WR inseriscili in un nuovo array e usali.
muru,

@WR Aggiunto questo nella risposta
wjandrea

1
Consiglierei di creare un nuovo array, per chiarezza.
wjandrea,

9

Se è qualcosa che vuoi fare molte volte, allora perché non creare una piccola funzione 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

Non è una cattiva idea. Tuttavia, non sembra dare /c/Users...- invece sta dando C:\Users\....
edesz,

@WR si scusa - errore copia-incolla. Per favore, provalo adesso.
steeldriver,

1
Grazie, utilizzo cdw () { f="${1/D://d}"; cd "/mnt${f//\\//}"; }nel sottosistema Windows per Linux, funziona come un incantesimo!
Weekend

2

Saresti in grado di ottenere questo in una riga usando sed

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

Nota che i due schemi devono rimanere separati, poiché le partite sono sostituite da sostituzioni diverse.


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

1

Questa domanda è ancora aperta a nuovi suggerimenti? Se è così, questo ti aiuterebbe?

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

Oh, e nel caso in cui la C debba essere lanciata in minuscolo:

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

Come panoramica:

$ 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

Qual è il motivo per l'utilizzo '^C'?
edesz,

1
^ indica l'inizio della riga, altrimenti tutte le occorrenze di C diventeranno minuscole ... dovrebbe esserci

Devo aggiungere che anche gli altri suggerimenti funzionano. Molti comandi Unix possono fare lo stesso lavoro, quindi dipende da te quale stile di soluzione preferisci usare.

Non avevo chiesto prima ^che fosse stato usato anche in altre risposte qui. Grazie per la risposta e la spiegazione.
edesz,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.