announcement : link-batch.zsh, to generate symlinks batches

cross-posted from: lemmy.world/post/1838642

link-batch is a minimalist script that generate symlinks from a list in a text file. Usage :

<pre style="background-color:#ffffff;">
<span style="color:#323232;">link-batch.zsh link-list.txt
</span>

where link-list.txt contains two columns : the first one for the links and the second one for the targets. Example :

<pre style="background-color:#ffffff;">
<span style="color:#323232;">~/.config/kitty	~/myfiles/config/kitty
</span><span style="color:#323232;">~/.config/nvim	~/myfiles/config/neovim
</span><span style="color:#323232;">~/.config/MuseScore	~/myfiles/config/MuseScore/$HOST
</span><span style="color:#323232;">...
</span>

The two columns must be separated by a tab.

Shell vars like $HOME or $HOST are evaluated to their values.

Can be used to quickly deploy all home links in a fresh box.

gamma,
@gamma@programming.dev avatar

Nice work! I would have done some things differently, but this is very readable.

Two recommendations for reading the file:

  • Use the (z) and (Q) flags so that instead of using tabs to separate the targets, simply quoting each argument works.
  • Instead of two independent lists, use an associative array with map[$link]=$target. Then you can check for duplicate links while reading the list.
<pre style="background-color:#ffffff;">
<span style="color:#323232;">linksfile</span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#183691;">$</span><span style="color:#323232;">1
</span><span style="color:#323232;">
</span><span style="font-weight:bold;color:#a71d5d;">typeset </span><span style="color:#323232;">-gA linkmap
</span><span style="color:#323232;">
</span><span style="font-weight:bold;color:#a71d5d;">while </span><span style="color:#62a35c;">read </span><span style="color:#323232;">-r line
</span><span style="font-weight:bold;color:#a71d5d;">do
</span><span style="color:#323232;">	</span><span style="font-style:italic;color:#969896;"># -- fields
</span><span style="color:#323232;">	fields</span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;">(${(Q)${(z)line}})
</span><span style="color:#323232;">	</span><span style="font-style:italic;color:#969896;"># -- link
</span><span style="color:#323232;">	link</span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#183691;">${</span><span style="color:#323232;">(e)~fields[</span><span style="color:#0086b3;">1</span><span style="color:#323232;">]</span><span style="color:#183691;">}
</span><span style="color:#323232;">	</span><span style="font-style:italic;color:#969896;"># -- target
</span><span style="color:#323232;">	target</span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#183691;">${</span><span style="color:#323232;">(e)~fields[</span><span style="color:#0086b3;">2</span><span style="color:#323232;">]</span><span style="color:#183691;">}
</span><span style="color:#323232;">	</span><span style="font-style:italic;color:#969896;"># -- check if we've already seen this link
</span><span style="color:#323232;">	</span><span style="font-weight:bold;color:#a71d5d;">if </span><span style="color:#323232;">(( $</span><span style="font-weight:bold;color:#a71d5d;">+</span><span style="color:#323232;">linkmap[$link] ))</span><span style="font-weight:bold;color:#a71d5d;">; then
</span><span style="color:#323232;">		</span><span style="color:#62a35c;">echo </span><span style="color:#183691;">"'$</span><span style="color:#323232;">link</span><span style="color:#183691;">' targets both '$</span><span style="color:#323232;">linkmap</span><span style="color:#183691;">[$</span><span style="color:#323232;">link</span><span style="color:#183691;">]' and '$</span><span style="color:#323232;">target</span><span style="color:#183691;">', aborting"
</span><span style="color:#323232;">		</span><span style="color:#62a35c;">exit</span><span style="color:#323232;"> 1
</span><span style="color:#323232;">	</span><span style="font-weight:bold;color:#a71d5d;">fi
</span><span style="color:#323232;">	</span><span style="font-weight:bold;color:#a71d5d;">if </span><span style="color:#62a35c;">[ </span><span style="color:#323232;">-z </span><span style="color:#183691;">"$</span><span style="color:#323232;">target</span><span style="color:#183691;">" </span><span style="color:#62a35c;">] </span><span style="font-weight:bold;color:#a71d5d;">|| </span><span style="color:#62a35c;">[ </span><span style="color:#323232;">-z </span><span style="color:#183691;">"$</span><span style="color:#323232;">link</span><span style="color:#183691;">" </span><span style="color:#62a35c;">]</span><span style="font-weight:bold;color:#a71d5d;">; then
</span><span style="color:#323232;">		</span><span style="color:#62a35c;">echo </span><span style="color:#183691;">"Empty link or target provided, skipping"
</span><span style="color:#323232;">		</span><span style="font-weight:bold;color:#a71d5d;">continue
</span><span style="color:#323232;">	</span><span style="font-weight:bold;color:#a71d5d;">fi
</span><span style="color:#323232;">	linkmap[$link]</span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#183691;">$</span><span style="color:#323232;">target
</span><span style="font-weight:bold;color:#a71d5d;">done < </span><span style="color:#323232;">$linksfile
</span>

Then later, you can iterate over each key-value pair:

<pre style="background-color:#ffffff;">
<span style="font-weight:bold;color:#a71d5d;">for</span><span style="color:#323232;"> link target </span><span style="font-weight:bold;color:#a71d5d;">in </span><span style="color:#183691;">"${</span><span style="color:#323232;">(@kv)linkmap</span><span style="color:#183691;">}"</span><span style="font-weight:bold;color:#a71d5d;">; do
</span><span style="color:#323232;">	...
</span><span style="font-weight:bold;color:#a71d5d;">done
</span>
  • All
  • Subscribed
  • Moderated
  • Favorites
  • shell@programming.dev
  • slotface
  • kavyap
  • thenastyranch
  • everett
  • tacticalgear
  • rosin
  • Durango
  • DreamBathrooms
  • mdbf
  • magazineikmin
  • InstantRegret
  • Youngstown
  • khanakhh
  • ethstaker
  • JUstTest
  • ngwrru68w68
  • cisconetworking
  • modclub
  • tester
  • osvaldo12
  • cubers
  • GTA5RPClips
  • normalnudes
  • Leos
  • provamag3
  • anitta
  • megavids
  • lostlight
  • All magazines