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

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

link-batch.zsh link-list.txt

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

~/.config/kitty	~/myfiles/config/kitty
~/.config/nvim	~/myfiles/config/neovim
~/.config/MuseScore	~/myfiles/config/MuseScore/$HOST
...

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.

  • GammaM
    link
    fedilink
    English
    arrow-up
    1
    ·
    edit-2
    1 year ago

    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.
    linksfile=$1
    
    typeset -gA linkmap
    
    while read -r line
    do
    	# -- fields
    	fields=(${(Q)${(z)line}})
    	# -- link
    	link=${(e)~fields[1]}
    	# -- target
    	target=${(e)~fields[2]}
    	# -- check if we've already seen this link
    	if (( $+linkmap[$link] )); then
    		echo "'$link' targets both '$linkmap[$link]' and '$target', aborting"
    		exit 1
    	fi
    	if [ -z "$target" ] || [ -z "$link" ]; then
    		echo "Empty link or target provided, skipping"
    		continue
    	fi
    	linkmap[$link]=$target
    done < $linksfile
    

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

    for link target in "${(@kv)linkmap}"; do
    	...
    done