0

I have code in bash for making latex file and in this fragment I want to make a table in a loop:

  while IFS= read -r line; do
    if [[ "$line" == *"comment"* ]]; then
  echo "${line#*comment: }" >> tif_list.txt

  IN="${line#*comment: }"

  data="$(echo $IN | tr "," "\n")"

  echo "       ${data[0]}" >> table.tex #name
  echo "     & ${data[2]}" >> table.tex #longitude
  echo "     & ${data[3]}" >> table.tex #latitude
  echo "     & ${data[4]}, ${data[5]}, ${data[6]}, ${data[7]}, ${data[8]}, ${data[9]}, " >> table.tex #dimensions
  echo "     & ${data[10]}" >> table.tex #time
  echo "     & ${data[1]}" >> table.tex #comments
  echo "     & \includegraphics[width=3.5cm]{${tif%.*}.png}\\" >> table.tex #adress
  echo "    \hline" >> table.tex
  echo "" >> table.tex

fi    

done < tif_info.txt

done

but echo first prints variables, and then my additional text:

     \hline
       Target0001
The operator places target notes here. Multiple lines OK.
55:51.6217 N
020:34.4421 E
C1
L3.0
W0.8
H1-1.0
H2-1.0
D16.8
2021:11:13 08:29:02.37
     & 
     & 
     & , , , , , , 
     & 
     & 
     & \includegraphics[width=3.5cm]{Target0001.png}\
    \hline

I want:

     \hline
     Target0001
     & The operator places target notes here. Multiple lines OK.
     & 55:51.6217 N
     & 020:34.4421 E
     & C1, L3.0, W0.8, H1-1.0, H2-1.0, D16.8 
     & 2021:11:13 08:29:02.37
     & \includegraphics[width=3.5cm]{Target0001.png}\
    \hline

I was trying to add /& or merge text by += but it doesn't change anything. I just need to make it work so I could have table with pictures and metadata from my tiff pictures.

My whole code:

#!/bin/bash

#program pobiera metadane tiff i zestawia w tabeli

echo "Starting..."

echo "\documentclass{article}" > table.tex echo "\usepackage{graphicx, tabularx}" >> table.tex echo "\usepackage[margin=0.5in]{geometry}" >> table.tex echo "\graphicspath{ {./images/} }" >> table.tex echo "" >> table.tex echo "\renewcommand\tabularxcolumn[1]{m{#1}}" >> table.tex echo "\newcolumntype{b}{X}" >> table.tex echo "\newcolumntype{s}{>{\hsize=.5\hsize}X}" >> table.tex echo "" >> table.tex echo "\begin{document}" >> table.tex echo "" >> table.tex echo "\begin{table}[htbp]" >> table.tex echo " \centering" >> table.tex echo " \begin{tabularx}{\textwidth} { " >> table.tex echo " | >{\centering\arraybackslash}s " >> table.tex echo " | >{\centering\arraybackslash}s " >> table.tex echo " | >{\centering\arraybackslash}s " >> table.tex echo " | >{\centering\arraybackslash}s " >> table.tex echo " | >{\centering\arraybackslash}s " >> table.tex echo " | >{\centering\arraybackslash}b " >> table.tex echo " | >{\centering\arraybackslash}b | }" >> table.tex echo " \hline" >> table.tex echo " name & longitude & latitude & dimensions & time & comments & picture \" >> table.tex echo " \hline" >> table.tex

echo "Serching comment..."

for tif in *.tif; do [ -f "$tif" ] || break identify -verbose "$tif" > tif_info.txt 2>&1

#convert "$tif" "${tif%.*}.png" 2>&1

while IFS= read -r line; do if [[ "$line" == "comment" ]]; then

  echo &quot;${line#*comment: }&quot; &gt;&gt; tif_list.txt

  IN=&quot;${line#*comment: }&quot;

  data=&quot;$(echo $IN | tr &quot;,&quot; &quot;\n&quot;)&quot;

  echo &quot;       ${data[0]}&quot; &gt;&gt; table.tex #name
  echo &quot;     &amp; ${data[2]}&quot; &gt;&gt; table.tex #longitude
  echo &quot;     &amp; ${data[3]}&quot; &gt;&gt; table.tex #latitude
  echo &quot;     &amp; ${data[4]}, ${data[5]}, ${data[6]}, ${data[7]}, ${data[8]}, ${data[9]}, &quot; &gt;&gt; table.tex #dimensions
  echo &quot;     &amp; ${data[10]}&quot; &gt;&gt; table.tex #time
  echo &quot;     &amp; ${data[1]}&quot; &gt;&gt; table.tex #comments
  echo &quot;     &amp; \includegraphics[width=3.5cm]{${tif%.*}.png}\\&quot; &gt;&gt; table.tex #adress
  echo &quot;    \hline&quot; &gt;&gt; table.tex
  echo &quot;&quot; &gt;&gt; table.tex

fi    

done < tif_info.txt

done

echo " \hline" >> table.tex echo " \end{tabularx}" >> table.tex echo "\end{table}" >> table.tex echo "" >> table.tex echo "\end{document}" >> table.tex echo "" >> table.tex

echo "Process completed."

  • 2
    You're using $data as if it is an array, but it's not. Also, please add expected output. You should also prefer printf over echo , but for text processing, you might want to use awk and not bash in the first place. – pLumo Feb 14 '22 at 21:46
  • What is $data? I was using this for cutting the string: https://stackoverflow.com/questions/918886/how-do-i-split-a-string-on-a-delimiter-in-bash – Karolina Pomian Feb 14 '22 at 21:55
  • 1
    You just change , to \n, it's still a string. – pLumo Feb 14 '22 at 21:58
  • Thank you, that explains where I've made mistake. I will try to use printf, I did not used awk because I don't know it. – Karolina Pomian Feb 14 '22 at 22:04
  • I strongly recommend that you learn the basics of perl scripting. Generating TeX output (and similar text processing tasks) is trivial in perl, much easier than trying to do it in sh....and runs much faster too. BTW, I routinely use perl to generate tables, TOCs, hyperref links, etc for TeX documents, because perl is good at text processing. Shell is not, it is lousy at text processing...it is, however, good at co-ordinating the execution of other programs, such as awk, sed, perl, grep, and many more. – cas Feb 15 '22 at 06:42
  • See also questions about perl on the TeX SE site, e.g, How to generate LaTeX documents with Perl. Also googling for "perl tex" or "perl latex" will come up with lots of blog posts like USING PERL IN YOUR LaTeX DESIGN FLOW – cas Feb 15 '22 at 06:46

1 Answers1

2
data="$(echo $IN | tr "," "\n")"

This is a scalar assignment, so you get a scalar variable. It'll contain a single multi-line string. (You could check with declare -p data.) In Bash,$var and ${var[0]} access the same element, regardless of the type of the variable. Either the one at index 0 if it's an array, or the lone value if it's a scalar.

You probably want to use read -a instead, e.g.

IN=foo,bar,doo
IFS=, read -r -a data  <<< "$IN"
echo "${#data[@]}" "${data[1]}"   # prints '3 bar'

In the stackexchange question you linked to, there's this:

mails=$(echo $IN | tr ";" "\n")
for addr in $mails
do ...

There, it's the unquoted expansion of $mails in the for loop that splits the contents on whitespace (or rather, whatever IFS contains, but by default it's whitespace). Now, that works, and you could similarly assign the result to an array with arr=($mails), but it'll split on any whitespace, and it'll process filename patterns, so values like foo bar and * will be trouble. See e.g http://mywiki.wooledge.org/WordSplitting and When is double-quoting necessary?

The top answer there has the same read -a that I wrote above. You want the -r too, to prevent it from messing up backslashes.

ilkkachu
  • 138,973
  • It works! I can't upvote but it helped me. – Karolina Pomian Feb 14 '22 at 22:07
  • Now I see that I missed this solution. Should I delete the question? – Karolina Pomian Feb 14 '22 at 22:13
  • @KarolinaPomian, well, meh. The worst that happens to the question is that it gets forgotten among the, umm, apparently 200 000+ other questions. Also you might not be able to, since there's an upvoted answer, and in theory someone might chance upon just this one and it might be helpful, and if you get a lot of deleted questions, the system stops taking questions from you (but no one will know if you just create a new account). Don't think too much about it... – ilkkachu Feb 14 '22 at 22:18