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
AAchoochoobut notchoochoo1.tsvand 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