Skip to content
Advertisement

Paste header line in multiple tsv (tab separated) files

I have multiple .tsv files named as choochoo1.tsv, choochoo2.tsv, … choochoo(nth).tsv files. I also have a main.tsv file. I want to extract the header line in main.tsv and paste over all choochoo(nth).tsv files. Please note that there are other .tsv files in the directory that I don’t want to change or paste header, so I can’t do *.tsv and select all the .tsv files (so need to select choochoo string for wanted files). This is what I have tried using bash script, but could not make it work. Please suggest the right way to do it.

for x in *choochoo; do
    head -n1 main.tsv > $x
done

Advertisement

Answer

You have a problem with the file glob, as well as the redirect:

  • the file glob will catch things like AAchoochoo but not choochoo1.tsv and not even AAchoochoo.tsv
  • the redirect will overwrite the existing files instead of adding to them. The redirect command for adding to a file is >>, but that will append text to the end and you want to prepend text in the beginning.

The problem with prepending text to an existing file, is that you have to open the file for both reading and writing and then stream both prepended text and original text, in order – and that is usually where people fail because the shell can’t open files like that (there is a slightly more complex way of doing this directly, by opening the file for both reading and writing, but I’m not going to address that further).

You might want to use a temporary file, something like this:

for x in choochoo[0-9]*.tsv; do
  mv "$x"{,.orig}
  (head -n1 main.tsv; cat "$x.orig") > $x
  rm "$x.orig"
done
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement