Now you've got me curious which came first, "paste" or "zip".
Python's zip function was added in PEP 201 [1], which credits the Haskell 98 report with the name. The same function appears in all prior versions of the Haskell language that I could find, dating back to Haskell 1.0 in 1990.
On the other hand, the GNU coreutils version of paste[2] has copyright dates going all the way back to 1984, which presumably means it was derived from UNIX System V or an even earlier version.
The miranda language (which predates haskell) had a zip function. According to wikipedia, miranda was released in 1985, but I dont know if zip was in the standard miranda environment back then. The comments in the source code say:
The following is included for compatibility with Bird and Wadler (1988).
The normal Miranda style is to use the curried form `zip2'.
> zip :: ([*],[**])->[(*,**)]
> zip (x,y) = zip2 x y
which suggests a slightly later origination of zip.
if you know the separator, you can use `cut` -- not an unzip per se (doesn't give you the full separated lists, without calling it multiple times anyway) but approximately equal to the awk line
EDIT: Actually, I'd never committed 4th. It was just sitting here in my local scrap. So I guess I counted to three, realized at some later date I needed four, copied 3rd to 4th, then never committed.
Oh. Apparently I also have 'nth', which was exactly what I wanted:
> echo a b c d | nth 0 3
a d
The solution I came up with at the time:
#!/bin/bash
c=""
for n in "$@"
do
n=$((n+1))
args="${args}${c}\$$n"
c=', '
done
awk "{ print ${args}; }"
Nowadays I'd write it like:
awk "{ print $(echo "$@" | args math '1+{}' | replace '^' '$' | trim | joinlines ', '); }"
But I admit both are equally cryptic, and the former might even be more readable.
Hmm. Does xargs give you a way to skip the first arg? xargs -n 2 I {} almost works, but you’d need a way to extract a specific arg out of the {}. Which I just realized I don’t know how to do.
“(at 0 {})” would be a nice construction.
But then of course now you’re writing xargs -n 2 -I {} echo (at 1 {}) instead of just awk {print $2}, so it’s mission failed successfully.
Kinda-sorta related, you can pipe to a multivariable loop:
paste <(printf "a\nb\nc\n") <(printf "1\n2\n3\n") | while
read x y; do echo "$y -- $x"; done
Kinda silly for this example, but very useful in things like `kubectl` pipelines -- you can do something like this:
kubectl get pods --all-namespaces | awk '{print $1 " " $2}' | grep "doesntexist" | while read x y; do kubectl delete pod $y --namespace $x --wait=false; done
This lets you list all pods in a cluster, grep a selection of them by name, and delete them in a batch, regardless of which namespace they are in, while shuffling the order of args into different flags.
But of course it can’t be named zip because that’s the compressor, so I’m really asking whether there’s an unpaste.
I guess the closest is awk {print $1;}, but it makes me wince every time I write it. (I already know that would give syntax errors as written here.)