我正在搜索一个文件,比如“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实现?请帮助找到解决此类问题的一般解决方案。
答案 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'
。这将适用于具有换行符的文件名。