我正在使用脚本使用命令获取文件的最后 n-2 行,然后使用 echo 将这些行打印到文件中。
last_n2_lines=`tail -n+3 $file`
echo "$last_n2_lines" >> $file
这里的这个回显从文件末尾删除了一个尾随的新行。供参考
尾 -n+3 文件 > file.new
运行良好。
来自手册: http ://www.gnu.org/software/bash/manual/bashref.html#Command-Substitution
3.5.4 命令替换
命令替换允许命令的输出替换命令本身。当命令包含如下时,会发生命令替换:
$(command)
或者
`command`
Bash 通过执行命令并将命令替换替换为命令的标准输出来执行扩展,并删除任何尾随的换行符。嵌入的换行符不会被删除,但它们可能会在分词过程中被删除。命令替换 $(cat file) 可以替换为等效但更快的 $(< file)。
当使用旧式反引号形式的替换时,反斜杠保留其字面含义,除非后面跟着“$”、“`”或“\”。前面没有反斜杠的第一个反引号终止命令替换。使用 $(command) 形式时,括号之间的所有字符组成命令;没有人受到特殊对待。
命令替换可能是嵌套的。要在使用反引号形式时嵌套,请使用反斜杠转义内部反引号。
如果替换出现在双引号中,则不会对结果执行分词和文件名扩展。
强调我的。所以这不是一个错误。这是一个特点。
您可以通过使用来保存尾随的空行readarray
来保存数据和printf
输出。
就像是:
readarray last_n2_lines < <(tail -n+3 $file)
printf "%s" "${last_n2_lines[@]}" > ${file}.new
演示:
$ cat test; echo end
1
2
3
4
end
$ tail -n+3 test ; echo end
3
4
end
$ readarray data < <(tail -n+3 test)
$ printf "%s" "${data[@]}" ; echo end
3
4
end
解释:
readarray data
将标准输入中的行读入名为data
.cmd1 < <(cmd2 param1 param2 ...)
将 的输出重定向cmd2 param1 param2 ...
到标准输入 if cmd1
。小心语法:它必须是< [space] <(...)
, 之间没有空格 , 两者之间<(
需要空格< <
。所以在第一行之后,data
包含所有tail -n+3
输出的行。数组中的每一项都是包含行终止符的输入行。
以下是访问每个元素的方法。请注意,为数组中定义的每个项目打印两行:数组中的一行(包含换行符),以及由添加的换行符echo
。
$ echo "${data[0]}"
3
$ echo "${data[1]}"
4
$ echo "${data[2]}"
$ echo "${data[3]}"
$ echo "${data[4]}" # out of bounds
$
${data[@]}
扩展到数组的所有元素data
printf "%s" param1 param2 ...
打印其所有参数不变(即不添加或删除行终止符)。所以第二条语句打印回读入的所有内容,保持不变。