Your loop is almost correct apart from the fact that the write
command is not the command that you want to use. Instead, use printf
with a redirection. You also need to make sure to skip the initial line, which we can do in a number of different ways. Below, I'm using tail -n +2
, but you could also use sed 1d
.
tail -n +2 InputFIle.txt |
while IFS=, read -r name string; do
printf '%s\n' "$string" >"$name".smi
done
Note that this assumes that the filename is written to only once, as if you have the same value in the first column on two or more lines, the later lines would cause the data already written to the file be overwritten. You may therefore possibly want to change >
to >>
to append to the output file. This change would require you to additionally delete the files if you want to run the code twice (or you'll get duplicated data in the output).
A possibly more efficient way to do this would be to use awk
like so:
awk -F, 'NR > 1 { print $2 >($1 ".smi") }' InputFIle.txt
This prints the second comma-delimited field to the filename given by the first field. It skips the initial line by testing NR
(the number of records read so far) against 1.
This does not suffer from the same issue as the shell loop. The output file would be truncated (emptied or created) upon the first print
to it, and subsequent outputs would then be appended.
If you have further fields on some lines, the awk
variant would need to be modified to print all fields apart from the first:
awk -F, 'NR > 1 { name = $1; sub("[^,]*,",""); print >(name ".smi") }' InputFIle.txt
This saves the first field in a separate variable, name
, and then removes that field from the original line with sub()
. It then prints the remaining line to the file.
write "$smile" "$name".smi
tryecho "$smile" >"$name".smi
I can write this as an answer.