Daniel
Daniel

Reputation: 12026

Using the `paste` and being aware of input filenames

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

Answers (2)

fedorqui
fedorqui

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

123
123

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

Related Questions