为什么 echo 在与其合并的其他文本之前打印字符串变量?

为什么 echo 在与其合并的其他文本之前打印字符串变量?

我在 bash 中有用于制作乳胶文件的代码,在这个片段中我想在循环中制作一个表:

  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

但 echo 首先打印变量,然后打印我的附加文本:

     \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

我想:

     \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

我试图通过 += 添加 /& 或合并文本,但它不会改变任何内容。我只需要让它工作,这样我就可以拥有包含 tiff 图片中的图片和元数据的表格。

我的整个代码:

#!/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 "${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

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."

答案1

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

这是一个标量赋值,因此您得到一个标量变量。它将包含一个多行字符串。 (您可以使用 进行检查declare -p data。)在 Bash 中,无论变量的类型如何,$var都可以访问相同的元素。如果是数组,则为${var[0]}索引处的值;如果是标量,则为单独的值。0

您可能想改用read -a,例如

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

在您链接到的 stackexchange 问题中,有这样的内容:

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

$mails在那里,循环中的未加引号的扩展将for空格上的内容分割(或者更确切地说,IFS包含任何内容,但默认情况下它是空格)。现在作品,并且您可以类似地将结果分配给一个数组arr=($mails)它会分裂任何空白,它会处理文件名模式,因此像foo bar和 之类的值*会很麻烦。参见例如 http://mywiki.wooledge.org/WordSplitting什么时候需要双引号?

read -a那里的最佳答案与我上面写的相同。你-r也想要这个,以防止它弄乱反斜杠。

相关内容