假设输入参数是几个文件的FULL路径。说,
/abc/def/file1
/abc/def/ghi/file2
/abc/def/ghi/file3
/abc/def
? file1
,/ghi/file2
和/ghi/file3
? 最佳答案
给定第1部分的答案(通用前缀),第2部分的答案很简单;您可以将前缀切成每个名称,这可以通过sed
和其他选项来完成。
因此,有趣的部分是找到通用前缀。最小公共(public)前缀为/
(例如,对于/etc/passwd
和/bin/sh
)。 (根据定义)最大的公共(public)前缀存在于所有字符串中,因此我们只需要将其中一个字符串拆分为多个段,然后将可能的前缀与其他字符串进行比较即可。在大纲中:
split name A into components
known_prefix="/"
for each extra component from A
do
possible_prefix="$known_prefix/$extra/"
for each name
do
if $possible_prefix is not a prefix of $name
then ...all done...break outer loop...
fi
done
...got here...possible prefix is a prefix!
known_prefix=$possible_prefix
done
有一些行政上的细节需要处理,例如名称中的空格。另外,允许的武器是什么。这个问题被标记为
bash
,但是允许使用哪些外部命令(例如Perl)?一个未定义的问题-假设名称列表为:
/abc/def/ghi
/abc/def/ghi/jkl
/abc/def/ghi/mno
最长的公共(public)前缀
/abc/def
或/abc/def/ghi
是吗?我将假定最长的公共(public)前缀是/abc/def
。 (如果您真的希望它是/abc/def/ghi
,那么将/abc/def/ghi/.
用作第一个名称。)此外,还有调用详细信息:
longest_common_prefix
和'path_without_prefix`)吗? 两条命令比较容易:
prefix=$(longest_common_prefix name1 [name2 ...])
suffix=$(path_without_prefix /pre/fix /pre/fix/to/file [...])
如果存在前缀,
path_without_prefix
命令将删除该前缀,如果前缀不以该名称开头,则保留该参数不变。longest_common_prefix
longest_common_prefix()
{
declare -a names
declare -a parts
declare i=0
names=("$@")
name="$1"
while x=$(dirname "$name"); [ "$x" != "/" ]
do
parts[$i]="$x"
i=$(($i + 1))
name="$x"
done
for prefix in "${parts[@]}" /
do
for name in "${names[@]}"
do
if [ "${name#$prefix/}" = "${name}" ]
then continue 2
fi
done
echo "$prefix"
break
done
}
测试:
set -- "/abc/def/file 0" /abc/def/file1 /abc/def/ghi/file2 /abc/def/ghi/file3 "/abc/def/ghi/file 4"
echo "Test: $@"
longest_common_prefix "$@"
echo "Test: $@" abc/def
longest_common_prefix "$@" abc/def
set -- /abc/def/ghi/jkl /abc/def/ghi /abc/def/ghi/mno
echo "Test: $@"
longest_common_prefix "$@"
set -- /abc/def/file1 /abc/def/ghi/file2 /abc/def/ghi/file3
echo "Test: $@"
longest_common_prefix "$@"
set -- "/a c/d f/file1" "/a c/d f/ghi/file2" "/a c/d f/ghi/file3"
echo "Test: $@"
longest_common_prefix "$@"
输出:
Test: /abc/def/file 0 /abc/def/file1 /abc/def/ghi/file2 /abc/def/ghi/file3 /abc/def/ghi/file 4
/abc/def
Test: /abc/def/file 0 /abc/def/file1 /abc/def/ghi/file2 /abc/def/ghi/file3 /abc/def/ghi/file 4 abc/def
Test: /abc/def/ghi/jkl /abc/def/ghi /abc/def/ghi/mno
/abc/def
Test: /abc/def/file1 /abc/def/ghi/file2 /abc/def/ghi/file3
/abc/def
Test: /a c/d f/file1 /a c/d f/ghi/file2 /a c/d f/ghi/file3
/a c/d f
path_without_prefix
path_without_prefix()
{
local prefix="$1/"
shift
local arg
for arg in "$@"
do
echo "${arg#$prefix}"
done
}
测试:
for name in /pre/fix/abc /pre/fix/def/ghi /usr/bin/sh
do
path_without_prefix /pre/fix $name
done
输出:
abc
def/ghi
/usr/bin/sh
关于bash shell脚本查找几个文件的最接近的父目录,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12340846/