GNU/Linux >> Tutoriels Linux >  >> Linux

Décomposition des spécifications de chemin en plus long préfixe commun + suffixe ?

Étant donné deux spécifications de chemin Unix absolues , on pourrait décomposer chaque spécification comme la concaténation d'un préfixe commun le plus long et d'un suffixe spécifique. Par exemple,

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

Existe-t-il un ou plusieurs utilitaires Unix pour calculer une telle décomposition ? (J'ai ajouté "ou utilitaires" au cas où il existe des utilitaires distincts pour calculer le préfixe commun le plus long et pour calculer les chemins relatifs.)

(Je me rends compte qu'il ne serait pas extrêmement difficile de coder de tels utilitaires, mais j'essaie de privilégier les outils plus ou moins standards par rapport aux outils sur mesure, dans la mesure du possible.)

J'écris "path spec" plutôt que "path" pour éviter des problèmes comme l'existence (des chemins) dans un système de fichiers donné, des liens, etc.

Réponse acceptée :

Vous pouvez le faire dans une boucle shell. Le code ci-dessous devrait fonctionner avec toutes sortes de chemins étranges avec des barres obliques supplémentaires ; si tous vos chemins sont de la forme /foo/bar , vous pouvez vous en sortir avec quelque chose de plus 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
}

Vous pouvez également déterminer le préfixe commun le plus long des deux chaînes et le réduire à son dernier / caractère (sauf lorsque le préfixe commun est uniquement constitué de barres obliques).

Connexe :Comment afficher la sortie Tail -f avec des couleurs en utilisant uniquement Awk et afficher le reste de la sortie ?
Linux
  1. Une brève introduction aux unités de chemin

  2. Comment ajouter correctement un chemin à un chemin ?

  3. Shebangs indépendants du chemin?

  4. CD vers un répertoire de nom inconnu dans un chemin connu ?

  5. quel python vs PYTHONPATH

Bash Scripting - Déclaration de cas

Que faire en cas de panique du noyau Linux

Passer à virt-manager

Comment faire écho dans le fichier

Linux :ajouter un répertoire à PATH

Hacher le nom d'hôte dans une couleur