Werner Lehmann
Werner Lehmann

Reputation: 911

Using a bash variable as file argument

In bash, is there a better way to pass a variable as file argument than process substitution and echo -n?

v1='...'
v2='...'
comm <(echo -n "$v1") <(echo -n "$v2")

The following works for one file argument, at the cost of some readability:

comm <(echo -n "$v1") - <<<"$v2"

Maybe it is a little bit faster? Is there a better option for 2+ files? Basically, I am looking for the opposite of v1=$(<filename).

Upvotes: 1

Views: 1002

Answers (2)

Ed Morton
Ed Morton

Reputation: 203665

$ v1=$(seq 1 3); v2=$(seq 2 4)

$ comm /dev/fd/3 3<<<"$v1" /dev/fd/4 4<<<"$v2"
1
                2
                3
        4

In the above 3<<<"$v1" and 4<<<"$v2" is making file descriptors 3 and 4 point to the temp files generated by the <<<s and then running comm on those file descriptors. Using awk you can see that happens:

$ awk 'BEGIN{for (i in ARGV) print i, ARGV[i]} {print FILENAME, $0}' /dev/fd/3 3<<<"$v1" /dev/fd/4 4<<<"$v2" 
0 awk
1 /dev/fd/3
2 /dev/fd/4
/dev/fd/3 1
/dev/fd/3 2
/dev/fd/3 3
/dev/fd/4 2
/dev/fd/4 3
/dev/fd/4 4

You can change the command line order of FD assignment vs usage if you find some other arrangement more readable and you can keep going, e.g.:

$ v3=$(seq 4 6); v4=$(seq 6 8)

$ paste /dev/fd/3 3<<<"$v1" /dev/fd/4 4<<<"$v2" /dev/fd/5 5<<<"$v3" /dev/fd/6 6<<<"$v4"
1       2       4       6
2       3       5       7
3       4       6       8

but you should really question why you're doing that if you do find yourself considering it as chances are there's a better approach for whatever it is you really need to do.

See https://unix.stackexchange.com/a/148153/133219 for more info.

Upvotes: 3

vintnes
vintnes

Reputation: 2030

I may not understand, but it looks like you're overthinking it.

awk '{print $2}' "$v1" "$v2"

If {v1} and {v2} are not filenames, but data, you can use a heredoc:

awk '{print $2}' <<EOF
$v1
$v2
EOF

Or a here-string:

awk '{print $2}' RS=: <<< "$v1:$v2"

Upvotes: 0

Related Questions