GNU/Linux >> Linux Esercitazione >  >> Linux

Scomposizione delle specifiche del percorso nel prefisso comune più lungo + suffisso?

Dati due percorsi Unix assoluti specifiche , è possibile scomporre ciascuna specifica come la concatenazione di un prefisso comune più lungo e di un suffisso specifico. Ad esempio,

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

Esiste un'utilità (o utilità) Unix per calcolare tale scomposizione? (Ho aggiunto "o utilità" nel caso ci siano utilità separate per il calcolo del prefisso comune più lungo e per il calcolo dei percorsi relativi.)

(Mi rendo conto che non sarebbe estremamente difficile codificare tali utilità, ma cerco di dare la priorità a strumenti più o meno standard rispetto a quelli personalizzati, quando possibile.)

Scrivo "specifica del percorso" anziché "percorso" per aggirare problemi come l'esistenza (dei percorsi) in un determinato filesystem, collegamenti, ecc.

Risposta accettata:

Puoi farlo in un ciclo di shell. Il codice seguente dovrebbe funzionare con tutti i tipi di percorsi strani con barre aggiuntive; se tutti i tuoi percorsi sono nella forma /foo/bar , puoi farla franca con qualcosa di più semplice.

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
}

In alternativa, determina il prefisso comune più lungo delle due stringhe e ritaglialo fino all'ultimo / carattere (tranne quando il prefisso comune è costituito esclusivamente da barre).

Correlati:come eseguire l'output di Tail -f con i colori utilizzando solo Awk e mostrare il resto dell'output?
Linux
  1. Come aggiungere in modo pulito a $ percorso?

  2. Regex caso Unix?

  3. CD in una directory con nome sconosciuto in un percorso noto?

  4. Creazione di una nuova directory in C

  5. Ignora maiuscole e minuscole in glob() su Linux

Bash Scripting – Case Statement

Cosa fare in caso di panico del kernel Linux

Passaggio a virt-manager

Come fare eco in un file

Linux:aggiungi una directory a PATH

Hash hostname in un colore