没有由>>生成的新行

时间:2017-03-21 17:36:55

标签: bash

我有以下代码片段在文件中选择两个行号,提取这些行之间的所有内容,用制表符替换新行字符并将它们放在输出文件中。我希望在一个循环中提取的所有行都在同一行上,但是在不同循环上提取的行将在新行上进行。

for ((i=1; i<=numTimePoints; i++)); do  
    # Get the starting point for line extraction. This is just an integer.
    startScan=$(($(echo "${dataStart}" | sed -n ${i}p)+1))  
    # Get the end point for line extraction. This is just an integer.          
    endScan=$(($(echo "${dataEnd}" | sed -n ${i}p)-1)) 
    # From file ${file}, take all lines between ${startScan} and ${endScan}. Replace new lines with tabs and output to file ${tmpOutputFile}    
    head -n ${endScan} ${file} | tail -n $((${endScan}-${startScan}+1)) | tr "\n" "\t" >> ${tmpOutputFile}   
done

此脚本主要按预期工作,但所有新行都附加到上一行,而不是放在新行上(我认为>>会这样做)。换句话说,如果我现在要cat ${tmpOutputFile} | wc,那么它会返回0 12290400 181970555。谁能指出我做错了什么?

1 个答案:

答案 0 :(得分:2)

任何重定向,包括>>,都与创建换行没有任何关系 - 重定向操作本身不会生成输出,换行符或其他方式;它们只控制文件描述符(stdout,stderr等)所连接的位置,它是执行那些负责内容的写入的程序。

因此,您的tr '\n' '\t' 完全阻止将新行添加到输出文件中 - 没有人可以来自那个没有通过管道

请考虑以下内容:

while read -r startScan <&3 && read -r endScan <&4; do
  # generate your output
  head -n "$endScan" "$file" | tail -n $(( endScan - startScan + 1 )) | tr '\n' '\t'
  # append your newline
  printf '\n'
done 3<<<"$dataStart" 4<<<"$dataEnd" >"$tmpOutputFile"

注意:

  • 我们不需要支付运行sed以提取startScanendScan的费用,而是从他们的内容创建的herestrings中读取一行。 dataStartdataEnd
  • 我们重定向到我们的输出文件一次,并重复使用该文件句柄进行整个循环(通过多个命令 - 首先是管道,然后是printf
  • 我们实际上正在运行printf来生成该换行符,而不是期望它以魔法隐式创建。