Windows で 2 つの変数を結合すると、その変数が破壊されます。

Windows で 2 つの変数を結合すると、その変数が破壊されます。

関数を渡すときに〜を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.exeCR-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の場合、#最短一致プレフィックスを削除します。 。

おすすめ記事