仅列出文件的公共父目录

时间:2014-09-12 18:47:28

标签: linux bash shell

我正在搜索一个文件,比如“file1.txt”,而find命令的输出如下所示。

/home/nicool/Desktop/file1.txt
/home/nicool/Desktop/dir1/file1.txt
/home/nicool/Desktop/dir1/dir2/file1.txt

在上述情况下,我只想要公共父目录,在上面的例子中是“/ home / nicool / Desktop”。如何使用bash实现?请帮助找到解决此类问题的一般解决方案。

3 个答案:

答案 0 :(得分:2)

此脚本读取行并在每次迭代中存储公共前缀:

# read a line into the variable "prefix", split at slashes
IFS=/ read -a prefix

# while there are more lines, one after another read them into "next",
# also split at slashes
while IFS=/ read -a next; do
    new_prefix=()

    # for all indexes in prefix
    for ((i=0; i < "${#prefix[@]}"; ++i)); do
        # if the word in the new line matches the old one
        if [[ "${prefix[i]}" == "${next[i]}" ]]; then
            # then append to the new prefix
            new_prefix+=("${prefix[i]}")
        else
            # otherwise break out of the loop
            break
        fi
    done

    prefix=("${new_prefix[@]}")
done

# join an array
function join {
    # copied from: http://stackoverflow.com/a/17841619/416224
    local IFS="$1"
    shift
    echo "$*"
}

# join the common prefix array using slashes
join / "${prefix[@]}"

示例:

$ ./x.sh <<eof
/home/nicool/Desktop1/file1.txt
/home/nicool/Desktop2/dir1/file1.txt
/home/nicool/Desktop3/dir1/dir2/file1.txt
eof
/home/nicool

答案 1 :(得分:1)

lcp() {
    local prefix path
    read prefix

    while read path; do
        while ! [[ $path =~ ^"$prefix" ]]; do
            [[ $prefix == $(dirname "$prefix") ]] && return 1
            prefix=$(dirname "$prefix")
        done
    done

    printf '%s\n' "$prefix"
    return 0
}

这会找到所有标准输入行的最长公共前缀。

$ find / -name file1.txt | lcp
/home/nicool/Desktop

答案 2 :(得分:1)

我认为没有内置的bash,但您可以使用此脚本,并将find传输到其中。

read -r FIRSTLINE
DIR=$(dirname "$FIRSTLINE")

while read -r NEXTLINE; do
  until [[ "${NEXTLINE:0:${#DIR}}" = "$DIR" || "$DIR" = "/" ]]; do
    DIR=$(dirname "$DIR")
  done
done

echo $DIR

为了增加安全性,请在查找中使用-print0,并将read语句调整为-d '\0'。这将适用于具有换行符的文件名。