Bash-Shell-Skript, um das nächstgelegene übergeordnete Verzeichnis mehrerer Dateien zu finden

8

Angenommen, die Eingabeargumente sind die vollständigen Pfade mehrerer Dateien. Sag,

%Vor%
  1. Wie kann ich den Verzeichnisnamen /abc/def in einem Bash-Shell-Skript erhalten?
  2. Wie kann ich nur file1 , /ghi/file2 und /ghi/file3 ?
  3. erhalten
Chang 09.09.2012, 16:37
quelle

5 Antworten

4

Angesichts der Antwort auf Teil 1 (das gemeinsame Präfix) ist die Antwort für Teil 2 einfach; Sie schneiden das Präfix von jedem Namen ab, was unter anderem mit sed geschehen könnte.

Der interessante Teil ist dann, das gemeinsame Präfix zu finden. Das minimale gemeinsame Präfix ist / (z. B. für /etc/passwd und /bin/sh ). Das maximale gemeinsame Präfix ist (per Definition) in allen Strings vorhanden, daher müssen wir einfach einen der Strings in Segmente aufteilen und mögliche Präfixe mit den anderen Strings vergleichen. Im Überblick:

%Vor%

Es gibt einige administrative Details, z. B. Leerzeichen in Namen. Was sind die erlaubten Waffen? Die Frage ist mit bash markiert, aber welche externen Befehle sind erlaubt (zB Perl)?

Ein undefiniertes Problem - Angenommen, die Liste der Namen lautete:

%Vor%

Ist das längste gemeinsame Präfix /abc/def oder /abc/def/ghi ? Ich gehe davon aus, dass das längste gemeinsame Präfix hier /abc/def ist. (Wenn Sie wirklich möchten, dass es /abc/def/ghi ist, dann verwenden Sie /abc/def/ghi/. für den ersten der Namen.)

Außerdem gibt es Aufrufdetails:

  • Wie wird diese Funktion oder dieser Befehl aufgerufen?
  • Wie werden die Werte zurückgegeben?
  • Sind das ein oder zwei Funktionen oder Befehle ( longest_common_prefix und 'path_without_prefix')?

Zwei Befehle sind einfacher:

  • prefix=$(longest_common_prefix name1 [name2 ...])
  • suffix=$(path_without_prefix /pre/fix /pre/fix/to/file [...])

Der Befehl path_without_prefix entfernt das Präfix, wenn es vorhanden ist, und lässt das Argument unverändert, wenn das Präfix den Namen nicht startet.

longest_common_prefix

%Vor%

Test:

%Vor%

Ausgabe:

%Vor%

pfad_ohne_präfix

%Vor%

Test:

%Vor%

Ausgabe:

%Vor%     
Jonathan Leffler 09.09.2012, 17:37
quelle
2

Eine eher "portable" Lösung in dem Sinne, dass sie keine bash-spezifischen Funktionen verwendet: Definieren Sie zuerst eine Funktion, um das längste gemeinsame Präfix von zwei Pfaden zu berechnen:

%Vor%

Dann verwenden Sie es für eine lange Liste von Wörtern:

%Vor%

Mit Ihrer Eingabe gibt es

%Vor%

Wie Jonathan Leffler darauf hingewiesen hat, ist die zweite Frage, wenn Sie das einmal haben, trivial.

    
Idelic 09.09.2012 21:17
quelle
2

Hier ist eine , die nachweislich mit beliebig komplexe Dateinamen (enthält Zeilenumbrüche, Backspaces und ähnliches):

%Vor%     
l0b0 11.09.2012 11:27
quelle
0

Mir scheint, dass die folgende Lösung viel einfacher ist.

Wie bereits erwähnt, ist nur Teil 1 schwierig. Teil 2 ist einfach mit sed.

Teil 1 kann in zwei Teile geteilt werden:

  1. Finden des längsten gemeinsamen Präfixes aller Strings
  2. Stellen Sie sicher, dass dieses Präfix ein Verzeichnis ist, und wenn es nicht abgeschnitten wird, um das entsprechende Verzeichnis zu erhalten

Es kann mit dem folgenden Code getan werden. In diesem Beispiel werden aus Gründen der Übersichtlichkeit nur 2 Strings verwendet, aber eine while-Schleife gibt Ihnen das, was Sie wollen, mit n Strings.

%Vor%

was natürlich in nur einer Zeile umgeschrieben werden kann:

%Vor%     
Vic Seedoubleyew 07.11.2015 18:09
quelle
-2

So rufen Sie das Verzeichnis von Eltern ab:

%Vor%

gibt / abc / def

Und um den Dateinamen zu erhalten

%Vor%

gibt Datei1

Und je nach Ihrer Frage, um nur Name des nächsten übergeordneten Verzeichnisses zu erhalten, verwenden Sie

%Vor%

gibt def     Code hier eingeben

    
djadmin 09.09.2012 16:44
quelle

Tags und Links