将文件输出限制为仅 2 行

limiting file output to only 2 lines

我 ping 了一系列地址并将延迟结果附加到一个文件中(每个地址都有一个单独的文件)。我正在尝试将文件限制为仅包含最后 2 个条目。

$outpath=/opt/blah/file.txt
resp_str="0.42"
echo $resp_str >> $outpath

tail -2 $outpath > $outpath

如果没有 tail,文件会随着新数据的增加而继续增长(本例中仅为 .42)。但是当我调用 tail 时,它会写出一个空文件。如果我将尾部输出重定向到一个不同名称的文件,那么我会得到预期的结果。我可以在阅读文件时不写出文件吗?有没有简单的解决办法?

这是完整的脚本:

OUT_PATH=/opt/blah/sites/
TEST_FILE=/opt/blah/test.txt

while IFS=, read -r ip name; do
    if [[ "$ip" != \#* ]]; then
        RESP_STR=$( ping -c 1 -q $ip | grep rtt| awk '{print }' | awk -F/ '{ print ; }')
        echo $RESP_STR >> "$OUT_PATH""test/"$name".txt"
    fi
done << $TEST_FILE

您可以使用管道 | 将一个命令的输出发送到另一个命令,在本例中为 tail.
然后我们可以使用 >> 追加到文件中。如果我们使用 >,我们每次都会覆盖文件,所有以前的内容都会丢失。
此示例每次将目录中的最后 2 个文件写入 log.txt 运行.

ls  | tail -2 >> log.txt

假设:

  • 需要为并行、并发进程编写代码(使用临时文件将要求每个进程都有一个唯一命名的临时文件)
  • 继续编写支持大量操作的代码(即减少 creating/destroying 临时文件的开销)

使用 mktemp 创建临时文件的一个想法......我们将其包装在一个函数中以便于使用:

keep2 () {

    # Usage: keep2 filename "new line of text"

    [[ ! -f "${tmpfile}" ]] &&
    tmpfile=$(mktemp)

    tail -1 "" > "${tmpfile}"
    { cat "${tmpfile}"; echo ""; } > ""
}

备注:

  • 硬编码的 -1 (tail -1) 可以参数化或引用 user-defined 环境变量
  • OP可以根据需要更改输入参数的顺序

参加试驾;

> logfile

for ((i=1;i<=5;i++))
do
    echo "######### $i"
    keep2 logfile "$i"
    cat logfile
done

这会生成:

######### 1
1
######### 2
1
2
######### 3
2
3
######### 4
3
4
######### 5
4
5

在 OP 的代码中,以下行:

echo $RESP_STR >> "$OUT_PATH""test/"$name".txt"

将替换为:

keep2 "$OUT_PATH""test/"$name".txt" "${RESP_STR}"

tail -2 $outpath > $outpath

>tail 开始读取之前截断文件。

您需要缓冲 tail 的输出,然后再将其写回该文件。使用 sponge 实现:

tail -2 $outpath | sponge $outpath