Wie erstelle ich symbolische Links zu allen Dateien (Dateiklassen) in einem Verzeichnis?

43

Ich möchte symbolische Links ( ln -s) zu allen Dateien (oder einer Dateiklasse, zB endend mit .bar) in einem bestimmten Verzeichnis erstellen . Angenommen, ich bin im CWD und Typ ls ../source/*.bargibt mir

foo.bar
baz.bar

Wie kann ich die Parameterliste übergeben, zu ln -sder sie schließlich aufgelöst wird?

ln -s ../source/foo.bar
ln -s ../source/baz.bar

Natürlich weiß ich, dass ich ein Bash-Skript schreiben kann, aber es sollte etwas Einfacheres geben, xargsda es - zumindest für mich - eine gemeinsame Aufgabe zu sein scheint.

Dastrobu
quelle

Antworten:

75

ln nimmt mehrere Argumente an, aber vergessen Sie in diesem Fall nicht, ein Zielverzeichnis anzugeben.

In Ihrem Beispiel .ist das Zielverzeichnis also so einfach wie

ln -s ../source/*.bar .

Von man ln; Der obige Befehl verwendet die 3. Form:

ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)
ln [OPTION]... TARGET                  (2nd form)
ln [OPTION]... TARGET... DIRECTORY     (3rd form)
ln [OPTION]... -t DIRECTORY TARGET...  (4th form)
  • Erstellen Sie im ersten Formular einen Link zu TARGET mit dem Namen LINK_NAME.
  • Erstellen Sie im 2. Formular einen Link zu TARGET im aktuellen Verzeichnis.
  • Erstellen Sie in der 3. und 4. Form Verknüpfungen zu jedem ZIEL im VERZEICHNIS.
mpy
quelle
5
Du hast mir gerade 5 Minuten meines Lebens gerettet, die es wert sind, dass einer von ihnen einen Kommentar hinterlässt. :-)
Moodboom
Dies funktioniert nicht, wenn keine Dateien vorhanden sind *.bar. Es wird eine Verknüpfung mit dem Namen erstellt "*.bar", die nicht Ihren Wünschen entspricht.
Nimrod
1
@Nimrod: Das stimmt, aber Sie können bash mitteilen, dass ein Fehler gemeldet werden soll shopt -s failglob. siehe zB unix.stackexchange.com/a/216227/33390 (Das Äquivalent in zsh ist setopt nomatch, das standardmäßig aktiviert ist)
mpy
: klatschen: schön!
Chris Schmitz
3

Verwenden find

certainDir="/path/to/dir"
find -name "*.bar" -exec ln -s {} "$certainDir" \;

Denken Sie auch daran, vollständige Pfade (soweit möglich) mit Symlinks zu verwenden.

ich schaue nur
quelle
2
Danke, aber nicht wahr find $certainDir -name "*.bar" -exec ln -s {} \;? Und warum sollte ich vollständige Pfade verwenden? Ich finde es sehr praktisch zu wissen, dass Links intakt bleiben, wenn ich einen Verzeichnisbaum mit internen Links verschiebe.
Dastrobu
Das hängt davon ab, wo Sie die Verzeichnisse symbolisieren möchten. Und ich kann mich nicht erinnern, warum vollständige Pfade eine gute Idee sind. Vielleicht waren es harte Links, aber das habe ich mir aus einem bestimmten Grund in den Kopf gesetzt. Hmmm.
Justbrowsing
Danke, Ihre Antwort ist großartig. Da die Antwort von mpy die einfachere Lösung der Frage ist, geht der Punkt zu ihm / ihr. Ich würde beide Antworten akzeptieren, wenn ich könnte.
Dastrobu
3

Sie können entweder mit globstar (bash / zsh set by:) rekursiv versuchen shopt -s globstar:

ls -vs ../**/*.bar .

Hinweis: -vFür ausführliche Informationen hinzugefügt .

Oder wenn die Liste zu lang ist, verwenden Sie das findDienstprogramm:

find .. -name \*.bar -exec ln -vs "{}" dest/ ';'

Dadurch werden Verknüpfungen im aktuellen Ordner erstellt dest/oder in geändert ..

Kenorb
quelle
Der zweite ist die richtige Antwort.
Nimrod
0

cpmit -sOption kann ein Softlink erstellt werden (oder -lfür Hardlink).

Aus dem aktuellen Verzeichnis kann folgendermaßen verwendet werden:

$ cp -s ../path/with/scripts/* .

In deinem Fall wird es so sein:

$ cp -s ../source/*.bar .
cy8g3n
quelle