我有以下代码片段在文件中选择两个行号,提取这些行之间的所有内容,用制表符替换新行字符并将它们放在输出文件中。我希望在一个循环中提取的所有行都在同一行上,但是在不同循环上提取的行将在新行上进行。
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
。谁能指出我做错了什么?
答案 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
以提取startScan
和endScan
的费用,而是从他们的内容创建的herestrings中读取一行。 dataStart
和dataEnd
printf
)printf
来生成该换行符,而不是期望它以魔法隐式创建。