As part of this bash script I worked on recently I have been playing a bit with cut
and tr
. These are old Unix commands and I haven’t used them that much. It’s mostly been a bit of sed
or awk
(am no expert in either of them) but as part of creating this script I was re-introduced to cut
and tr
when Googling for some solution.
The cut
command cuts text along a delimiter and can output the fields you choose. The tr
command can translate text.
This is not tutorial but here’s an example of where I used these two today. I have a bunch of docker volumes I want to list just the names of. The default output is thus:
1 2 3 4 5 6 |
$ docker volume ls DRIVER VOLUME NAME local kea-knot_keaconfig local kea-knot_kealeases local kea-knot_knotconfig local kea-knot_knotzones |
Sure, I can pipe a grep kea-knot
to get just the lines with volume names, but how can I extract just the volume name? This is where cut
comes into play. The following should in theory get me the second column:
1 |
docker volume ls | grep kea-knot | cut -d ' ' -f 2 |
This does not however. It only returns a bunch of blank lines. Why? Because I am telling it to cut along a space, and between local
and the kea-knot_keaconfig
text for instance there’s multiple spaces. This the second column is actually the fifth or sixth column.
So what I need here is a way to trim the spaces (or get cut
to match on one or more spaces – it doesn’t seem to do that). Here’s where its buddy tr
comes into play. tr
can also squeeze characters. So if I do tr -s ' '
it will squeeze multiple spaces into a single one. And you can guess where the story goes from here… I pass that to cut
who will dutifully get me the second field as expected. :)
1 2 3 4 5 |
$ docker volume ls | grep kea-knot | tr -s ' ' | cut -d ' ' -f 2 kea-knot_keaconfig kea-knot_kealeases kea-knot_knotconfig kea-knot_knotzones |
Tada!
In this specific case however if I had read the docker volume
command docs a bit more I would have discovered that adding a --quiet
switch to docker volume ls
would have got me just the volume names!
1 2 3 4 5 |
$ docker volume ls --quiet | grep kea-knot kea-knot_keaconfig kea-knot_kealeases kea-knot_knotconfig kea-knot_knotzones |
Oh well. Wouldn’t have had a bit of fun with cut
and tr
then would I? :o)
Anyways, why was I doing this? Because I wanted to move multiple volumes from one Docker host to another. I had blogged about a single volume previously, now I loop over that:
1 2 3 |
for VOLUME in `docker volume ls --quiet | grep kea-knot`; do docker run --rm -v $VOLUME:/$VOLUME alpine tar -czv --to-stdout -C /$VOLUME . > $VOLUME.tgz ; done |
Copy these over to the destination host and loop over to import them:
1 2 3 |
for VOLUME in kea-knot*.tgz; do cat $VOLUME | docker run --rm -i -v ${VOLUME%.tgz}:/${VOLUME%.tgz} alpine tar xzf - -C /${VOLUME%.tgz} ; done |