GNU/Linux >> Tutoriales Linux >  >> Linux

¿Descomposición de las especificaciones de la ruta en el prefijo común más largo + el sufijo?

Dadas dos especificaciones absolutas de ruta Unix , uno podría descomponer cada especificación como la concatenación de un prefijo común más largo y un sufijo específico. Por ejemplo,

/abc/bcd/cdf     -> /abc/bcd + cdf
/abc/bcd/chi/hij -> /abc/bcd + chi/hij

¿Existe una utilidad (o utilidades) de Unix para calcular dicha descomposición? (Agregué "o utilidades" en caso de que haya utilidades separadas para calcular el prefijo común más largo y para calcular rutas relativas).

(Me doy cuenta de que no sería extremadamente difícil codificar tales utilidades, pero trato de dar prioridad a las herramientas que son más o menos estándar sobre las hechas a medida, siempre que sea posible).

Escribo "especificación de ruta" en lugar de "ruta" para evitar problemas como la existencia (de las rutas) en un sistema de archivos dado, enlaces, etc.

Respuesta aceptada:

Puedes hacer eso en un bucle de shell. El siguiente código debería funcionar con todo tipo de caminos extraños con barras inclinadas adicionales; si todas sus rutas son de la forma /foo/bar , puedes salirte con la tuya con algo más simple.

split_common_prefix () {
  path1=$1
  path2=$2
  common_prefix=
  ## Handle initial // specially
  case $path1 in
    //[!/]*) case $path2 in
               //[!/]*) common_prefix=/ path1=${path1#/} path2=${path2#/};;
               *) return;;
             esac;;
    /*) case $path2 in
          /*) :;;
          *) return;;
        esac;;
    *) case $path2 in /*) return;; esac;;
  esac
  ## Normalize multiple slashes
  trailing_slash1= trailing_slash2=
  case $path1 in */) trailing_slash1=/;; esac
  case $path2 in */) trailing_slash2=/;; esac
  path1=$(printf %s/ "$path1" | tr -s / /)
  path2=$(printf %s/ "$path2" | tr -s / /)
  if [ -z "$trailing_slash1" ]; then path1=${path1%/}; fi
  if [ -z "$trailing_slash2" ]; then path2=${path2%/}; fi
  ## Handle the complete prefix case (faster, necessary for equality and
  ## for some cases with trailing slashes)
  case $path1 in
    "$path2")
      common_prefix=$path1; path1= path2=
      return;;
    "$path2"/*)
      common_prefix=$path2; path1=${path1#$common_prefix} path2=
      return;;
  esac
  case $path2 in
    "$path1"/*)
      common_prefix=$path1; path1= path2=${path2#$common_prefix}
      return;;
  esac
  ## Handle the generic case
  while prefix1=${path1%%/*} prefix2=${path2%%/*}
        [ "$prefix1" = "$prefix2" ]
  do
    common_prefix=$common_prefix$prefix1/
    path1=${path1#$prefix1/} path2=${path2#$prefix1/}
  done
}

Alternativamente, determine el prefijo común más largo de las dos cadenas y recórtelo a su último / carácter (excepto cuando el prefijo común consta únicamente de barras).

Relacionado:¿Cómo hacer cola -f de salida con colores usando solo Awk y mostrar el resto de la salida?
Linux
  1. Una breve introducción a las unidades de camino

  2. Regex de caso de Unix?

  3. ¿Cd a un directorio de nombre desconocido en una ruta conocida?

  4. Creando un nuevo directorio en C

  5. Ignorar mayúsculas y minúsculas en glob() en Linux

Bash Scripting – Declaración de caso

Qué hacer en caso de pánico en el kernel de Linux

Cambiando a virt-manager

Cómo hacer eco en un archivo

Linux:agregar un directorio a PATH

Hash nombre de host en un color