Reputation: 12026
Let's say I have files: foo.tsv
and bar.tsv
, whose contents are shown below:
foo.tsv
1
2
3
4
5
bar.tsv
a
b
c
d
e
If I run paste foo.tsv bar.tsv > foo_bar.tsv
I get:
foo_bar.tsv
1 a
2 b
3 c
4 d
5 e
Though this is very nice, I'd like to automatically name foo_bar.tsv
to eliminate the possibility of ending up with a misleading file, e.g., in case of typos.
Let's say:
paste foo.tsv baz.tsv > foo_bar.tsv # foo_bar should have been foo_baz here.
In the simple case of 2 inputs is hard to get something wrong, but if I do:
paste foo.tsv baz.tsv bar.tsv baz.tsv > foo_baz_bar_baz.tsv
things are likely to get messy.
Is there a way of automatically naming the output file? How can I make the redirection operator aware of its inputs?!
Upvotes: 1
Views: 80
Reputation: 289525
You can use an array to keep track of the files you want to paste
together:
files=("foo.tsv" "bar.tsv")
Then, paste "${files[@]}"
will expand to paste "foo.tsv" "bar.tsv"
.
Finally, to redirect to a file whose name is based on the arguments, you can use something like
$ IFS=_
$ echo "${files[*]%.*}"
foo_bar
That is, remove everything from the last dot to all the elements in the array and then print them together setting the internal field separator to _
.
Doing the same thing over all the elements in the array is described in Shell parameter expansion on arrays and printing them together using ${var[*]}
is described in Bash Reference Manual → Special Parameters (kudos to anishane for the suggestion in comments).
Then, it is a matter of redirecting the paste
command to a file created with this printf
:
command > "$(echo "${files[*]%.*}".tsv)"
All together:
files=("foo.tsv" "bar.tsv")
paste "${files[@]}" > "$(IFS=_; echo "${files[*]%.*}".tsv)"
Upvotes: 4
Reputation: 11216
You could also set up a function that does most of the work for you
pastefile(){
for i in "$@";do
newfile+="${i%.*}_"
done
ext="${1##*.}"
paste "$@" > "${newfile%_}.${ext}"
}
Run as
$ pastefile foo.tsv bar.tsv
$ cat foo_bar.tsv
1 a
2 b
3 c
4 d
5 e
Will also work with filenames with spaces.
Upvotes: 3