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 notchoochoo1.tsv
and not evenAAchoochoo.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