関数を渡すときに〜をWindowsユーザーディレクトリに変換するLinuxのWindowsシステムで、Bash用に何かを書こうとしていますwinpath
。これまでは、Windowsディレクトリを検索してUnixパスに変換でき、2つのパスをリンクする/home/[username]/
の~
に問題がありました。
次のように2つの変数があります。
$target_path=/home/jacob/Repositories
$user_path=/mnt/c/Users/Jacob
(実際にプログラムで検索していますが、違いはないと思います。)
その後、/home/jacob
削除し$target_path
てそのままにしてください/Repositories
。
ターゲットは$user_path
変更されたターゲットと結合され、$target_path
以下を出力します。
/mnt/c/Users/Jacob/Repositories
このために、私は次のようにします。
target_path=$user_path$target_path
ただし、何らかの理由で認知出力は次のとおりです。
/RepositoriesJacob
$user_path
私が直接出力しても合って、$target_path
直接出力しても合うのでこれは言葉になりません。だから2つを組み合わせると混乱が発生します。
関連ラインは8-20です。この点(全体のコードは下に貼り付けました)。
winpath() {
# get the Windows user path
user_path=$(/mnt/c/Windows/System32/cmd.exe /C echo %HOMEDRIVE%%HOMEPATH%)
# expand the specified path
target_path=$(readlink -f $1)
# change ~ to $user_path (WIP)
if grep -q "^/home/" <<< $target_path; then
# convert Windows-style user path to Unix-style (i.e. from C:\Users\[username] to /mnt/c/Users/[username])
temp_user_path=$(echo "$user_path" | sed -e 's|\\|/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/mnt/\L\1\E/\2|')
# remove /home/[username]/ from $target_path
target_path=$(echo "$target_path" | sed -e 's|^/home/\(.*\)/\(.*\)|/\2|')
# output $temp_user_path for debugging
echo $temp_user_path # correctly outputs
# output $target_path for debugging
echo $target_path # correctly outputs
# combine the variables
echo $temp_user_path$target_path # DOES NOT correctly output (?)
fi
# check if a Windows path is getting parsed
if grep -q "^/mnt/[a-z]/" <<< $target_path; then
# swap /mnt/[a-z]/ with [A-Z]:/ and / with \
echo $(echo "$target_path" | sed -e 's|^\(/mnt/\([a-z]\)/\)\(.*\)|\U\2:\\\E\3|' -e 's|/|\\|g')
else
# return the user's home directory if a Unix path was parsed
echo $user_path
fi
}
編集:いいね、変ですね…Macで試してみるとうまくいきます。たぶんこれはWSLのバグですか?
編集2:追加のテストを行った結果、これは2つの出力の組み合わせに関連しているようですsed
。文字列を変数として入力して組み合わせてみるとうまくいきます。よく。
ベストアンサー1
はい、追加のキャリッジリターンが問題です。
プロセス置換はプロセスの出力から最後の改行文字を削除しますが、cmd.exe
CR-LFペアが出力されると、キャリッジリターン文字は最後に保持されますuser_path
。印刷時にCRは、出力が印刷されると行の先頭に戻ります。Repositories
長さは同じ/mnt/c/Users
なので、下のスラッシュは論理的に整列されます(単語が壊れているように見える場合とは反対)。
を使用してBashから末尾のCRを削除できます${user_path%$'\r'}
。 (${var%pattern}
変数からパターンに一致するサフィックスを削除)
's|^/home/\(.*\)/\(.*\)|/\2|'
また、2番目のsed()があまりにも情熱的だと思います。最初の.*
ものは一致できる最も長い文字列と一致するため、/home/user/foo/bar
代わりに/bar
パラメータ/foo/bar
拡張を使用してこれを実行できます${target_path#/home/*/}
。 1の場合、#
最短一致プレフィックスを削除します。 。