在shell中找到两个路径字符串的最长匹配

发布于 2025-01-04 23:29:34 字数 514 浏览 1 评论 0原文

我有两个像这样的字符串

/home/user/Desktop/aaaa/Final/
/home/user/Desktop/aaaa/folder3333/IMAG0486.jpg

我的结果字符串应该是这样的

/home/user/Desktop/aaaa/Final/folder3333/IMAG0486.jpg

,当我在这种情况下找到最长的匹配时,

意思

“/home/user/Desktop/aaaa”

然后我添加第二个字符串的其余部分

“文件夹3333/IMAG0486.jpg”

到第一个字符串

,结果字符串是

/home/user/Desktop/aaaa/Final/folder3333/IMAG0486.jpg

I have two strings like this

/home/user/Desktop/aaaa/Final/
/home/user/Desktop/aaaa/folder3333/IMAG0486.jpg

and my result string should be something like this

/home/user/Desktop/aaaa/Final/folder3333/IMAG0486.jpg

meaning when I find the longest match in this case

"/home/user/Desktop/aaaa"

then I add the rest of the second string

"folder3333/IMAG0486.jpg"

to the fist string

and the result string is

/home/user/Desktop/aaaa/Final/folder3333/IMAG0486.jpg

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

青瓷清茶倾城歌 2025-01-11 23:29:34

/ 上的路径拆分为数组。迭代数组直到找到差异,将第二个数组的其余部分添加到输出中。我在代码中留下了调试打印,通过删除它们可以显着缩短代码。

#! /bin/bash
s1=/home/user/Desktop/aaaa/Final/
s2=/home/user/Desktop/aaaa/folder3333/IMAG0486.jpg
expect=/home/user/Desktop/aaaa/Final/folder3333/IMAG0486.jpg
out=$s1

_IFS=$IFS
IFS=/
parts1=($s1)
parts2=($s2)
IFS=$_IFS

matching=1
for ((i=0;i<${#parts2[@]};i++)) ; do
    if [[ $matching && ${parts1[i]} == ${parts2[i]} ]] ; then
        echo same ${parts2[i]}
    else
        echo different ${parts1[i]} ${parts2[i]}
        matching=0
        out+=${parts2[i]}/
    fi
done
out=${out%/}

echo $expect
echo $out

Split the paths on / to arrays. Iterate over the arrays until you find the difference, add the rest of the second array to the output. I left the debugging prints in the code, by removing them it can be shortened significantly.

#! /bin/bash
s1=/home/user/Desktop/aaaa/Final/
s2=/home/user/Desktop/aaaa/folder3333/IMAG0486.jpg
expect=/home/user/Desktop/aaaa/Final/folder3333/IMAG0486.jpg
out=$s1

_IFS=$IFS
IFS=/
parts1=($s1)
parts2=($s2)
IFS=$_IFS

matching=1
for ((i=0;i<${#parts2[@]};i++)) ; do
    if [[ $matching && ${parts1[i]} == ${parts2[i]} ]] ; then
        echo same ${parts2[i]}
    else
        echo different ${parts1[i]} ${parts2[i]}
        matching=0
        out+=${parts2[i]}/
    fi
done
out=${out%/}

echo $expect
echo $out
药祭#氼 2025-01-11 23:29:34

对我有用并且可以工作单元测试

path_common()
{
    if [ -z "${2-}" ]
    then
        return 2
    fi

    # Remove repeated slashes
    for param
    do
        param=$(printf %s. "$1" | tr -s "/")
        set -- "$@" "${param%.}"
        shift
    done

    common_path=$1
    shift

    for param
    do
        while case ${param%/}/ in "${common_path%/}/"*) false;; esac; do
            new_common_path=${common_path%/*}
            if [ "$new_common_path" = "$common_path" ]
            then
                return 1 # Dead end
            fi
            common_path=$new_common_path
        done
    done
    printf %s "$common_path"
}

This works for me and has working unit tests:

path_common()
{
    if [ -z "${2-}" ]
    then
        return 2
    fi

    # Remove repeated slashes
    for param
    do
        param=$(printf %s. "$1" | tr -s "/")
        set -- "$@" "${param%.}"
        shift
    done

    common_path=$1
    shift

    for param
    do
        while case ${param%/}/ in "${common_path%/}/"*) false;; esac; do
            new_common_path=${common_path%/*}
            if [ "$new_common_path" = "$common_path" ]
            then
                return 1 # Dead end
            fi
            common_path=$new_common_path
        done
    done
    printf %s "$common_path"
}
风追烟花雨 2025-01-11 23:29:34

不如其他解决方案可靠,但对于常规情况效果很好:

#!/bin/bash

p1="/home/user/Desktop/aaaa/Final/"
p2="/home/user/Desktop/aaaa/folder3333/IMAG0486.jpg"

printf "%s|%s" "$p1" "$p2" | sed -e 's_^\(\(.*\)\/.*\)|\2/\(.*\)$_\1\3_'

Less reliable than other solutions, but works fine for regular cases:

#!/bin/bash

p1="/home/user/Desktop/aaaa/Final/"
p2="/home/user/Desktop/aaaa/folder3333/IMAG0486.jpg"

printf "%s|%s" "$p1" "$p2" | sed -e 's_^\(\(.*\)\/.*\)|\2/\(.*\)$_\1\3_'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文