Jak utworzyć dowiązania symboliczne do wszystkich plików (klasy plików) w katalogu?

43

Chciałbym utworzyć dowiązania symboliczne ( ln -s) do wszystkich plików (lub klasy plików, np. Kończących się na .bar) w określonym katalogu. Powiedz, że jestem w cwd, a typ ls ../source/*.bardaje mi

foo.bar
baz.bar

jak mogę przekazać listę parametrów, do ln -sktórej ostatecznie się rozwiązuje

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

Oczywiście wiem, że mogę napisać skrypt bash, ale powinno być coś prostszego xargs, ponieważ wydaje się to powszechnym zadaniem - przynajmniej dla mnie.

dastrobu
źródło

Odpowiedzi:

75

ln pobiera wiele argumentów, ale w takim przypadku nie zapomnij podać katalogu docelowego.

Tak więc w twoim przykładzie .jest katalog docelowy, więc powinien być tak prosty jak

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

Od man ln; powyższe polecenie używa trzeciej formy:

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)
  • W pierwszym formularzu utwórz link do TARGET o nazwie LINK_NAME.
  • W drugim formularzu utwórz link do TARGET w bieżącym katalogu.
  • W trzecim i czwartym formularzu utwórz linki do każdego CELU w KATALOGU.
mpy
źródło
5
Właśnie uratowałeś mi 5 solidnych minut mojego życia, na tyle warte, aby jeden z nich zostawił komentarz. :-)
moodboom
To nie działa, jeśli nie ma żadnych plików *.bar. Stworzy link z nazwą "*.bar", która nie jest tym, czego chcesz.
Nimrod,
1
@Nimrod: To prawda, ale możesz powiedzieć bashowi, że zamiast tego chcesz zgłosić błąd shopt -s failglob; patrz np. unix.stackexchange.com/a/216227/33390 (Odpowiednikiem w zsh jest setopt nomatch, który jest domyślnie włączony)
mpy
: klaskanie: miło!
Chris Schmitz
3

Posługiwać się find

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

Pamiętaj również, aby używać pełnych ścieżek (tam, gdzie to możliwe) z dowiązaniami symbolicznymi.

tylko przeglądam
źródło
2
Dzięki, ale czyż nie find $certainDir -name "*.bar" -exec ln -s {} \;? I dlaczego powinienem używać pełnych ścieżek? Uważam, że całkiem wygodnie jest wiedzieć, że linki pozostają nienaruszone, gdy poruszam drzewem katalogów, które mają jakieś wewnętrzne linki.
dastrobu,
To zależy od tego, gdzie chcesz dowiązać katalogi. I nie pamiętam, dlaczego pełne ścieżki są dobrym pomysłem, być może były to twarde linki, ale z jakiegoś powodu wypaliłem to sobie w głowie. Hmmm.
justbr Przeglądaj
Dzięki, twoja odpowiedź jest świetna. Ponieważ odpowiedź mpy jest prostszym rozwiązaniem pytania, chodzi o niego. Zaakceptowałbym obie odpowiedzi, gdybym mógł.
dastrobu,
3

Możesz spróbować rekurencyjnie za pomocą globstar (bash / zsh ustawiane przez:) shopt -s globstar:

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

Uwaga: Dodano -vdla pełnych.

Lub jeśli lista jest za długa, używając findnarzędzia:

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

Spowoduje to utworzenie łączy dest/lub zmianę .na bieżący folder.

kenorb
źródło
Druga to poprawna odpowiedź.
Nimrod,
0

cpz -sopcją można utworzyć miękkie linki (lub -ltwarde linki).

Z bieżącego katalogu można użyć w następujący sposób:

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

W twoim przypadku będzie tak:

$ cp -s ../source/*.bar .
cy8g3n
źródło