GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Zerlegung von Pfadangaben in längstes gemeinsames Präfix + Suffix?

Bei zwei beliebigen absoluten Unix-Pfad-Spezifikationen , könnte man jede Spezifikation als die Verkettung eines längsten gemeinsamen Präfixes und eines spezifischen Suffixes zerlegen. Beispiel:

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

Gibt es ein Unix-Dienstprogramm (oder Dienstprogramme), um eine solche Zerlegung zu berechnen? (Ich habe „oder Dienstprogramme“ hinzugefügt, falls es separate Dienstprogramme zum Berechnen des längsten gemeinsamen Präfixes und zum Berechnen relativer Pfade gibt.)

(Mir ist klar, dass es nicht sehr schwierig wäre, solche Dienstprogramme zu programmieren, aber ich versuche, wann immer möglich, Werkzeugen, die mehr oder weniger Standard sind, Vorrang vor maßgeschneiderten zu geben.)

Ich schreibe „Pfadspezifikation“ statt „Pfad“, um Probleme wie das Vorhandensein (der Pfade) in einem bestimmten Dateisystem, Links usw. zu umgehen.

Akzeptierte Antwort:

Sie können dies in einer Shell-Schleife tun. Der folgende Code sollte mit allen Arten von seltsamen Pfaden mit zusätzlichen Schrägstrichen funktionieren; wenn alle Ihre Pfade die Form /foo/bar haben , können Sie mit etwas Einfacherem davonkommen.

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
}

Bestimmen Sie alternativ das längste gemeinsame Präfix der beiden Zeichenfolgen und kürzen Sie es auf sein letztes / Zeichen (außer wenn das gemeinsame Präfix nur aus Schrägstrichen besteht).

Verwandte:Wie kann man Tail -f mit Farben nur mit Awk ausgeben und den Rest der Ausgabe anzeigen?
Linux
  1. Wie füge ich einen Pfad zu Pfad richtig hinzu?

  2. Unix-Fall-Regex?

  3. Cd in ein namensunbekanntes Verzeichnis in einem bekannten Pfad?

  4. Konvertieren Sie die ls-Ausgabe in csv

  5. Linux:in einen Dienst verarbeiten

Bash-Skripting – Case-Statement

Was tun bei einer Linux-Kernel-Panik?

Umstellung auf virt-manager

Wie Echo in Datei

Linux:Fügen Sie PATH ein Verzeichnis hinzu

Hash-Hostname in eine Farbe