найти самое длинное совпадение двух строк пути в оболочке - PullRequest
1 голос
/ 14 февраля 2012

У меня есть две строки, как это

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

и моя строка результата должна выглядеть примерно так

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

значение, когда я нахожу самое длинное совпадение в этом случае

"/ главная / пользователя / Desktop / AAAA"

затем я добавляю остаток второй строки

"folder3333 / IMAG0486.jpg"

до первой строки

и строка результата

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

Ответы [ 3 ]

0 голосов
/ 14 февраля 2012

Это работает для меня и имеет работающие модульные тесты :

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"
}
0 голосов
/ 14 февраля 2012

Менее надежен, чем другие решения, но отлично работает для обычных случаев:

#!/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_'
0 голосов
/ 14 февраля 2012

Разделить пути на / для массивов.Перебирайте массивы, пока не найдете разницу, добавьте остаток второго массива к выводу.Я оставил отладочные отпечатки в коде, удалив их можно значительно сократить.

#! /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
...