List only shared parent directories for files

I am looking for one file, say "file1.txt", and the output of the find command is similar to below.

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

In the above cases, I want to use only the shared parent directory, which is "/ home / nicool / Desktop" in the above case. How can this be achieved with bash? Please help find a common solution to this problem.

+5
source share
3 answers

This script reads the lines and stores a common prefix at each iteration:

 # 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[@]}" 

Example:

 $ ./x.sh <<eof /home/nicool/Desktop1/file1.txt /home/nicool/Desktop2/dir1/file1.txt /home/nicool/Desktop3/dir1/dir2/file1.txt eof /home/nicool 
+2
source
 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 } 

This finds the longest common prefix of all standard input lines.

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

I do not think bash is built in for this, but you can use this script and connect find to it.

 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 

For added security, use -print0 in your find and set the read statements to -d '\0' . This will work with file names that have newlines.

+1
source

Source: https://habr.com/ru/post/1202442/


All Articles