Linuxファイルパスに変換されたWindowsファイルパス


13

文字列としてbash変数にWindowsパスがあります:

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

このパスをで始まるLinuxパスに変換しようとしてい/c/Users...ます。

私の試み

次の作品:

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

問題

ここでは、ファイルパスを含む文字列に対してこれを実行しました。この質問をする理由は、Ubuntu 16.04のbashスクリプトで20個のそのような文字列を変換する必要があり、これを行うたびに変換ごとに2行を記述する必要があるためです。

質問

2つのコマンドを組み合わせる方法はありますか

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

一つのコマンドに?


1
forループ(および場合によっては配列)を使用します。変数も引用してください。
wjandrea

ありがとう。ループまたは配列でこれを行う方法の例を示していただけますか?
edesz

回答:


17

を使用して両方の置換を一度に行う方法がありますが、sed必ずしも必要ではありません。

この問題を解決する方法は次のとおりです。

  1. ファイル名を配列に入れる
  2. 配列の繰り返し

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

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

出力する代わりに出力を配列に入れたい場合は、echo行を割り当てに置き換えます。

  filenames_out+=( "$f" )

しかし、2つのファイルf1とがあった場合f2、どのように機能しますか?つまり、古いファイル名を置き換えることにより、新しいファイル名を配列に再割り当てするにはどうすればよいですか?
-edesz

@WRはemを新しい配列に入れて使用します。
ムル

@WR答えにそれを追加
-wjandrea

1
わかりやすくするために、新しいアレイを作成することをお勧めします。
-wjandrea

9

何度もやりたいことなら、小さなシェル関数を作成してみませんか?

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

それは悪い考えではありません。しかし、それは与えるようには見えません/c/Users...-代わりに与えることC:\Users\...です。
edesz

@WR謝罪-コピーアンドペーストエラー。今すぐお試しください。
スチールドライバー

1
おかげで、私cdw () { f="${1/D://d}"; cd "/mnt${f//\\//}"; }はLinuxのWindowsサブシステムで使用し、魅力のように動作します!
週末

2

これは、sedを使用して1行で実現できます。

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

それにもかかわらず、一致は異なる置換によって置き換えられるため、2つのパターンは別々のままでなければならないことに注意してください。


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

1

この質問はまだ新しい提案を受け入れていますか?もしそうなら、これはあなたを助けますか?

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

ああ、Cを小文字にキャストする必要がある場合:

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

概要として:

$ 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

使用する理由は何'^C'ですか?
edesz

1
^は行の始まりを意味します。そうしないと、Cのすべての出現が小文字になります...

他の提案も機能することを付け加えなければなりません。多くのUnixコマンドで同じ作業を行うことができるため、どのスタイルのソリューションを使用するかはユーザー次第です。

^ここで他のいくつかの回答でも使用されていることについては、以前に質問していません。答えと説明をありがとう。
-edesz
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.