【问题标题】:find the longest match of two path strings in shell在shell中找到两个路径字符串的最长匹配
【发布时间】:2012-02-14 10:28:58
【问题描述】:
我有两个这样的字符串
/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
【问题讨论】:
标签:
regex
bash
shell
string-matching
【解决方案1】:
将/ 上的路径拆分为数组。遍历数组直到找到差异,将第二个数组的其余部分添加到输出中。我在代码中留下了调试打印,通过删除它们可以显着缩短。
#! /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
【解决方案2】:
This 为我工作并且有工作 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"
}
【解决方案3】:
不如其他解决方案可靠,但适用于常规情况:
#!/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_'