Caminho de arquivo do Windows convertido em caminho de arquivo do Linux

13

Eu tenho um caminho do Windows em uma variável bash como uma string:

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

Eu estou tentando converter esse caminho em um caminho Linux começando com /c/Users....

Minha tentativa

Os seguintes trabalhos:

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

Problema

Aqui, eu fiz isso para uma string que contém o caminho do arquivo. A razão pela qual estou fazendo essa pergunta é que tenho que converter 20 dessas strings em um script bash no Ubuntu 16.04 e cada vez que faço isso, escrevo 2 linhas por conversão - está ocupando muito espaço!

Questão

Existe uma maneira de combinar os 2 comandos

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

em um comando?

edesz
fonte
1
Use um loop for (e talvez uma matriz). Também cite suas variáveis.
Wjandrea
Obrigado. Você poderia mostrar um exemplo de como fazer isso em um loop ou matriz?
Edesz 04/04

Respostas:

17

Haveria uma maneira de fazer as duas substituições ao mesmo tempo sed, mas não é necessário.

Aqui está como eu resolveria esse problema:

  1. Colocar nomes de arquivos na matriz
  2. Iterar sobre matriz

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 você deseja colocar a saída em uma matriz em vez de imprimir, substitua a echolinha por uma atribuição:

  filenames_out+=( "$f" )
wjandrea
fonte
Ok. Mas se eu tivesse 2 arquivos f1e f2, como isso funcionaria? Quero dizer, como reatribuir os novos nomes de arquivos à matriz, substituindo os antigos?
Edesz #
@WR colocá-los em uma nova matriz e usar isso.
Muru
@WR Agregado que na resposta
wjandrea
1
Eu recomendo fazer uma nova matriz, por uma questão de clareza.
Wjandrea
9

Se é algo que você deseja fazer várias vezes, por que não criar uma pequena função de 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
chave de aço
fonte
Isso não é uma má ideia. No entanto, parece não dar /c/Users...- ao contrário, está dando C:\Users\....
Edesz # 5/17
Desculpas do @WR - erro de copiar e colar. Por favor, tente agora.
steeldriver
1
Obrigado, eu uso cdw () { f="${1/D://d}"; cd "/mnt${f//\\//}"; }no subsistema Windows para Linux, funciona como um encanto!
Fim de semana
2

Você seria capaz de conseguir isso em uma linha usando sed

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

Observe que os dois padrões devem permanecer separados, pois as correspondências são substituídas por substituições diferentes.

taifwa
fonte
1
Sinônimo:file="$(sed 's|^C:|/c|; s|\\|/|g' <<< "$file")"
wjandrea 5/04
1

Essa pergunta ainda está aberta a novas sugestões? Se sim, isso ajudaria você?

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

Ah, e caso o C deva ser convertido para minúsculas:

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

Como uma visão geral:

$ 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

fonte
Qual o motivo do uso '^C'?
Edesz # 28/17
1
^ Meios início da linha, caso contrário, todas as ocorrências de C vai se tornar minúsculas ... deve haver alguma
Devo acrescentar que as outras sugestões também funcionam. Muitos comandos do Unix podem fazer o mesmo trabalho, então cabe a você qual estilo de solução você prefere usar.
Eu não havia perguntado anteriormente sobre o ^que foi usado em algumas outras respostas aqui também. Obrigado pela resposta e explicação.
Edesz # 28/17