bash 逐行将文件发送到记录器(原因限制 1024)

bash send file to logger line by line (cause limit 1024)

提问人:dckiller 提问时间:11/6/2023 最后编辑:dckiller 更新时间:11/9/2023 访问量:223

问:

我有一个 bash 脚本,我将数据发送到 syslog-ng 记录器。就我而言,问题是字符数超过 1024 个,因此被截断。 我已经设法生成了一个包含几行的文件,但它继续发送完整的块。

我想将文件发送到记录器并从 node-red 中检索它以返工。dhcp.leases

logger -t "wrtdhcpleasesreport" "$(echo "$(dumpWrtPresenceDhcp)")"

#/bin/sh
WRTPRESENCE_DHCP_LEASES="/tmp/wrtpresence_dhcp.leases"
DHCP_LEASES="/tmp/dhcp.leases"
#
dumpWrtPresenceDhcp ()
{
    echo "$(WrtPresenceDhcp)"
    sleep 1
    cat "${WRTPRESENCE_DHCP_LEASES}"
    return
}
WrtPresenceDhcp ()
{
    # Creating a file
    touch "${WRTPRESENCE_DHCP_LEASES}"
    touch "${WRTPRESENCE_DHCP_LEASES}.new"
    # Prints the dhcp.leases file in 1 line separated by | in wrtpresence_dhcp.leases.new.
    cat "${DHCP_LEASES}" | awk '{print $2";"$3";"$4}' | tr '\n' '|' > "${WRTPRESENCE_DHCP_LEASES}.new"
    # Move the wrtpresence_dhcp.leases.new file to wrtpresence_dhcp.leases.
    mv "${WRTPRESENCE_DHCP_LEASES}.new" "${WRTPRESENCE_DHCP_LEASES}"
    #Print 6 characters per line to get around the 1024 character limit.    
    awk '(NR % 6 == 1) {print; for(i=1; i<6 && getline ; i++) { print }; printf "\n"}' RS='|' ORS='|' "${WRTPRESENCE_DHCP_LEASES}" > "${WRTPRESENCE_DHCP_LEASES}.new"
    # Move the wrtpresence_dhcp.leases.new file to wrtpresence_dhcp.leases. 
    mv "${WRTPRESENCE_DHCP_LEASES}.new" "${WRTPRESENCE_DHCP_LEASES}"
    return
}
logger -t "wrtdhcpleasesreport" "$(echo "$(dumpWrtPresenceDhcp)")"
exit 0

我的第一次测试。结果很酷,但我没有注意到它停在 1024 个字符处。

Nov  5 11:15:01 WifiAP-01 wrtdhcpleasesreport: 
ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;h

这里发布的代码很酷,我有几行,但是当它在 1 次发送时,它不会改变限制中的任何内容。

Nov  5 11:17:01 WifiAP-01 wrtdhcpleasesreport: 
ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|
ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|
ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.1

我希望能够做到这一点。

Nov  5 11:17:01 WifiAP-01 wrtdhcpleasesreport: ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|
Nov  5 11:17:01 WifiAP-01 wrtdhcpleasesreport: ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|
Nov  5 11:17:01 WifiAP-01 wrtdhcpleasesreport: ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|
Nov  5 11:17:01 WifiAP-01 wrtdhcpleasesreport: ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|ab:ab:ab:ab:ab:ab;192.168.x.xxx;hostname|

我想发送

logger -t "wrtdhcpleasesreport" "$(echo "$(dumpWrtPresenceDhcp)")" line1

logger -t "wrtdhcpleasesreport" "$(echo "$(dumpWrtPresenceDhcp)")" line2

logger -t "wrtdhcpleasesreport" "$(echo "$(dumpWrtPresenceDhcp)")" line3...

示例文件(详细信息)/tmp/dhcp.leases

1 条线路等于 1 个设备 行 [0]= 毫秒 (x1000) 行 [1]= MAC 地址 行 [2]= IP 行 [3]= 主机名

0 ab:ab:ab:ab:ab:ab 192.168.1.12 Computer-1 *
1699250507 ab:ab:ab:ab:ab:ab 192.168.1.17 Computer-2 01:ab:ab:ab:ab:ab:ab
0 ab:ab:ab:ab:ab:ab 192.168.1.123 TV-1 ab:ab:ab:ab:ab:ab
1699243309 ab:ab:ab:ab:ab:ab 192.168.1.13 Iphone *
0 be:ab:ab:ab:ab:ab 192.168.1.34 Android-Children be:ab:ab:ab:ab:ab
0 fd:ab:ab:ab:ab:ab 192.168.1.56 Computer-3 *
0 cd:ab:ab:ab:ab:ab 192.168.1.124 Computer-4 01:cd:ab:ab:ab:ab:ab

我的项目

意识到我的编码局限性,我根据我左右阅读的内容调整了我的代码。我的代码不是最佳的,这是肯定的,但我同时也在学习。这是积极的一面。


测试解决方案

/tmp/test(我已经匹配了实际文件中的字符数)

0 00:01:00:00:00:00 192.168.1.01 one-one-one-oneo *
0 00:02:00:00:00:00 192.168.1.02 Two-two-twoo 01:00:02:00:00:00:00
0 00:03:00:00:00:00 192.168.1.003 three-three-thr 01:00:03:00:00:00:00
0 00:04:00:00:00:00 192.168.1.04 four-four-four-fou *
0 00:05:00:00:00:00 192.168.1.005 five-five-fiv 01:00:05:00:00:00:00
0 00:06:00:00:00:00 192.168.1.006 six-six-s *
0 00:07:00:00:00:00 192.168.1.07 seven-seven-sevenn *
0 00:08:00:00:00:00 192.168.1.008 eight-eight-e *
0 00:09:00:00:00:00 192.168.1.09 nine-nine-ninenin 01:00:09:00:00:00:00
0 00:10:00:00:00:00 192.168.1.10 ten-ten-ten-t 01:00:09:00:00:00:00
0 00:11:00:00:00:00 192.168.1.011 eleven-eleven 01:00:09:00:00:00:00
0 00:12:00:00:00:00 192.168.1.12 twelve-twelve-twe 01:00:09:00:00:00:00
0 00:13:00:00:00:00 192.168.1.13 thirteen-thirte *
0 00:14:00:00:00:00 192.168.1.14 fourteen-fourteen *
0 00:15:00:00:00:00 192.168.1.015 fifteen-fifteen-fi *
0 00:16:00:00:00:00 192.168.1.4 sixteen-sixteen-sixt *
0 00:17:00:00:00:00 192.168.1.17 seventeen-seven 01:00:09:00:00:00:00
0 00:18:00:00:00:00 192.168.1.018 eighteen-eig 01:00:09:00:00:00:00
0 00:19:00:00:00:00 192.168.1.019 nineteen-ninet *
0 00:20:00:00:00:00 192.168.1.020 twenty-twenty-twe 01:00:09:00:00:00:00
0 00:21:00:00:00:00 192.168.1.021 twentyone 01:00:09:00:00:00:00
0 00:22:00:00:00:00 192.168.1.22 twentytwo-twentytwo 01:00:09:00:00:00:00
0 00:23:00:00:00:00 192.168.1.6 twentythree-twentyt 01:00:09:00:00:00:00
0 00:24:00:00:00:00 192.168.1.24 twentyfour-twentyfo 01:00:09:00:00:00:00
0 00:25:00:00:00:00 192.168.1.25 twentyfiv *
0 00:26:00:00:00:00 192.168.1.26 twentysix-twenty 01:00:09:00:00:00:00
0 00:27:00:00:00:00 192.168.1.27 twentyseven-twent 01:00:09:00:00:00:00
0 00:28:00:00:00:00 192.168.1.28 twentyeigh 01:00:09:00:00:00:00
0 00:29:00:00:00:00 192.168.1.29 twentynine-twentyn 01:00:09:00:00:00:00
0 00:30:00:00:00:00 192.168.1.30 thirty-thirty-thir 01:00:09:00:00:00:00
0 00:31:00:00:00:00 192.168.1.31 thirtyone-thirty 01:00:09:00:00:00:00
1707029378 00:32:00:00:00:00 192.168.1.32 thirtytwo-t 01:00:09:00:00:00:00
0 00:33:00:00:00:00 192.168.1.33 thirtythre 01:00:09:00:00:00:00
0 00:34:00:00:00:00 192.168.1.4 thirtyfour-t 01:00:09:00:00:00:00

命令:

</tmp/test awk '{print $2,$3,$4}' OFS=';' ORS='|\r' |
tr -d '\r' | logger -t wrtdhcpleasesreport

结果:

Nov  6 12:22:58 WifiAP-01 wrtdhcpleasesreport: 00:01:00:00:00:00;192.168.1.01;one-one-one-oneo|00:02:00:00:00:00;192.168.1.02;Two-two-twoo|00:03:00:00:00:00;192.168.1.003;three-three-thr|00:04:00:00:00:00;192.168.1.04;four-four-four-fou|00:05:00:00:00:00;192.168.1.005;five-five-fiv|00:06:00:00:00:00;192.168.1.006;six-six-s|00:07:00:00:00:00;192.168.1.07;seven-seven-sevenn|00:08:00:00:00:00;192.168.1.008;eight-eight-e|00:09:00:00:00:00;192.168.1.09;nine-nine-ninenin|00:10:00:00:00:00;192.168.1.10;ten-ten-ten-t|00:11:00:00:00:00;192.168.1.011;eleven-eleven|00:12:00:00:00:00;192.168.1.12;twelve-twelve-twe|00:13:00:00:00:00;192.168.1.13;thirteen-thirte|00:14:00:00:00:00;192.168.1.14;fourteen-fourteen|00:15:00:00:00:00;192.168.1.015;fifteen-fifteen-fi|00:16:00:00:00:00;192.168.1.4;sixteen-sixteen-sixt|00:17:00:00:00:00;192.168.1.17;seventeen-seven|00:18:00:00:00:00;192.168.1.018;eighteen-eig|00:19:00:00:00:00;192.168.1.019;nineteen-ninet|00:20:00:00:00:00;192.168.1.020;twenty-twenty-twe|00:21:00:00:00:00;192.168.1.021;
Nov  6 12:22:58 WifiAP-01 wrtdhcpleasesreport: twentytwo-twentytwo|00:23:00:00:00:00;192.168.1.6;twentythree-twentyt|00:24:00:00:00:00;192.168.1.24;twentyfour-twentyfo|00:25:00:00:00:00;192.168.1.25;twentyfiv|00:26:00:00:00:00;192.168.1.26;twentysix-twenty|00:27:00:00:00:00;192.168.1.27;twentyseven-twent|00:28:00:00:00:00;192.168.1.28;twentyeigh|00:29:00:00:00:00;192.168.1.29;twentynine-twentyn|00:30:00:00:00:00;192.168.1.30;thirty-thirty-thir|00:31:00:00:00:00;192.168.1.31;thirtyone-thirty|00:32:00:00:00:00;192.168.1.32;thirtytwo-t|00:33:00:00:00:00;192.168.1.33;thirtythre|00:34:00:00:00:00;192.168.1.4;thirtyfour-t|

第 21 行和第 22 行之间缺少数据。 它应该在第 20 行停止,然后在第 21 行重新开始,以获得完全休息。

@Ed Morton 题外话 帮助您了解项目。我有一个路由器和一个运行 Openwrt 的接入点。我想在 homeassistant 下实时监控我的 wifi 设备。有许多解决方案,但每种解决方案的可靠性水平各不相同。我在互联网上找到了一个符合我期望的脚本,但它不适合家庭助理。所以我寻找最简单的方法来做到这一点。 该代码基于读取日志。因此,我找到了一个解决方案,可以通过node-red将我的Openwrt日志连接到homeassistant。默认情况下,在 Openwrt 中,当设备连接或断开连接时,它会创建一个包含其 mac 地址的条目。节点红色接收和处理。 要在 homeassistant 中拥有漂亮的设备,您需要一个名字,一个 ID。当设备连接时,我只知道mac地址。自动化所有这些并拥有一个好名字的最佳解决方案是在 dhcp.leases 文件中查找主机名。当 homeassistant 重新启动时出现问题,或者如果 node-red 错过了一些信息,它会认为每个人都不在,因为我已经连接了。该脚本允许您每 5 分钟发送一次连接到网络的所有设备。我借此机会发送 dhcp.leases 信息。 现在有了所有信息,我就可以在家庭助手中自动创建带有信息的设备。在哪个设备上连接路由器或接入点,在哪个天线上,它的名称,它的MAC地址,它的IP地址.....

bash 日志记录

评论

1赞 Ed Morton 11/6/2023
编辑您的问题,以阐明您要解决的问题,并包括简洁、可测试的样本输入和预期输出。你说长行是一个问题,但它们是从哪里来的,你想用它们做什么(截断它们?把它们换到下一行?别的什么?)还要告诉我们你为什么要这样做,而不仅仅是没有添加.logger ... "$(echo "$(dumpWrtPresenceDhcp)")"logger ... "$(dumpWrtPresenceDhcp)"echo
1赞 Ed Morton 11/6/2023
请尝试提出一个最小的可重现示例,其中包括一个最小的完整脚本,仅演示您寻求帮助的问题。我们不需要滚动条来读取代码、输入或输出。无论您寻求帮助什么问题,目前都隐藏在您问题的所有代码中,从而使我们更难为您提供帮助。
1赞 Ed Morton 11/6/2023
看起来您提供的命令行存在问题,但我无法弄清楚为什么您要在该函数中执行大部分操作(例如,写入一个文件,然后立即将其移动到另一个文件,将换行符转换为 s,然后使用 s 作为换行符再次读取文件, 尽量打印 6 个字符以避免 2024 个字符的限制等)因此,请提供示例输入、预期输出以及该函数中步骤的说明,以便我们为您提供帮助。WrtPresenceDhcp ()||
2赞 pjh 11/6/2023
Shellcheck 识别了代码的几个问题。它生成的报告包含指向有关问题以及如何解决这些问题的详细信息的链接。最好在所有新的和修改的 shell 代码上运行 Shellcheck
1赞 pjh 11/6/2023
请注意,最好避免使用ALL_UPPERCASE变量名称(如 ),因为存在与 shell 编程中使用的大量特殊ALL_UPPERCASE变量发生冲突的危险。请参阅更正 Bash 和 shell 脚本变量大小写DHCP_LEASES

答:

1赞 Ed Morton 11/6/2023 #1

试一试。

鉴于您在评论中说:

我打算每次发送 6 行 dhcp.leases

以下是 3 个选项,请根据您的输入和所需的输出格式选择一个。

选项 1:

给定此示例输入,从 https://stackoverflow.com/a/2143661/1745001 复制,然后长度加倍,因此它包含 6 个以上的租约:

$ cat /tmp/dhcp.leases
lease 192.168.20.4 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 00:00:00:00:00:00;
    uid 00:00:00:00:00:00;
    client-hostname "examle-workstation1";
}

lease 192.168.20.5 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 00:00:00:00:00:00;
}

lease 192.168.20.6 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 00:00:00:00:00:01;
    uid 00:00:00:00:00:01;
    client-hostname "examle-workstation2";
}


lease 192.168.20.7 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 01:00:00:00:00:00;
}

lease 192.168.20.4 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 00:00:00:00:00:00;
    uid 00:00:00:00:00:00;
    client-hostname "examle-workstation1";
}

lease 192.168.20.5 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 00:00:00:00:00:00;
}

lease 192.168.20.6 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 00:00:00:00:00:01;
    uid 00:00:00:00:00:01;
    client-hostname "examle-workstation2";
}


lease 192.168.20.7 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 01:00:00:00:00:00;
}

这将每秒调用一次,一次最多调用 6 个租约,因为它是最后一个参数:logger

$ cat tst.sh
#!/usr/bin/env bash

dhcp_leases='/tmp/dhcp.leases'

WrtPresenceDhcp() {
    awk -v maxLeases=6 -v OFS=';' '
        NF {
            gsub(/^[[:space:]]+|[[:space:]]+$/,"")
            lease = (linesCnt++ ? lease OFS : "") $0
        }
        $1 == "}" {
            leases = (numLeases++ ? leases "|" : "") lease
            if ( numLeases == maxLeases ) {
                print leases
                numLeases = 0
            }
            linesCnt = 0
            next
        }
        END {
            if ( numLeases ) {
                print leases
            }
        }
    ' "$dhcp_leases"
}

while IFS= read -r leases; do
    echo logger -t "wrtdhcpleasesreport" "$leases"
    sleep 1
done < <(WrtPresenceDhcp)

$ ./tst.sh
logger -t wrtdhcpleasesreport lease 192.168.20.4 {;starts 6 2009/06/27 00:40:00;;ends 6 2009/06/27 12:40:00;;hardware ethernet 00:00:00:00:00:00;;uid 00:00:00:00:00:00;;client-hostname "examle-workstation1";;}|lease 192.168.20.5 {;starts 6 2009/06/27 00:40:00;;ends 6 2009/06/27 12:40:00;;hardware ethernet 00:00:00:00:00:00;;}|lease 192.168.20.6 {;starts 6 2009/06/27 00:40:00;;ends 6 2009/06/27 12:40:00;;hardware ethernet 00:00:00:00:00:01;;uid 00:00:00:00:00:01;;client-hostname "examle-workstation2";;}|lease 192.168.20.7 {;starts 6 2009/06/27 00:40:00;;ends 6 2009/06/27 12:40:00;;hardware ethernet 01:00:00:00:00:00;;}|lease 192.168.20.4 {;starts 6 2009/06/27 00:40:00;;ends 6 2009/06/27 12:40:00;;hardware ethernet 00:00:00:00:00:00;;uid 00:00:00:00:00:00;;client-hostname "examle-workstation1";;}|lease 192.168.20.5 {;starts 6 2009/06/27 00:40:00;;ends 6 2009/06/27 12:40:00;;hardware ethernet 00:00:00:00:00:00;;}
logger -t wrtdhcpleasesreport lease 192.168.20.6 {;starts 6 2009/06/27 00:40:00;;ends 6 2009/06/27 12:40:00;;hardware ethernet 00:00:00:00:00:01;;uid 00:00:00:00:00:01;;client-hostname "examle-workstation2";;}|lease 192.168.20.7 {;starts 6 2009/06/27 00:40:00;;ends 6 2009/06/27 12:40:00;;hardware ethernet 01:00:00:00:00:00;;}

选项 2

另一方面,如果您在文本下显示的内容

/tmp/test(我已经匹配了实际文件中的字符数)

在您的问题中:

$ cat /tmp/dhcp.leases
0 00:01:00:00:00:00 192.168.1.01 one-one-one-oneo *
0 00:02:00:00:00:00 192.168.1.02 Two-two-twoo 01:00:02:00:00:00:00
0 00:03:00:00:00:00 192.168.1.003 three-three-thr 01:00:03:00:00:00:00
0 00:04:00:00:00:00 192.168.1.04 four-four-four-fou *
0 00:05:00:00:00:00 192.168.1.005 five-five-fiv 01:00:05:00:00:00:00
0 00:06:00:00:00:00 192.168.1.006 six-six-s *
0 00:07:00:00:00:00 192.168.1.07 seven-seven-sevenn *
0 00:08:00:00:00:00 192.168.1.008 eight-eight-e *
0 00:09:00:00:00:00 192.168.1.09 nine-nine-ninenin 01:00:09:00:00:00:00
0 00:10:00:00:00:00 192.168.1.10 ten-ten-ten-t 01:00:09:00:00:00:00
0 00:11:00:00:00:00 192.168.1.011 eleven-eleven 01:00:09:00:00:00:00
0 00:12:00:00:00:00 192.168.1.12 twelve-twelve-twe 01:00:09:00:00:00:00
0 00:13:00:00:00:00 192.168.1.13 thirteen-thirte *
0 00:14:00:00:00:00 192.168.1.14 fourteen-fourteen *
0 00:15:00:00:00:00 192.168.1.015 fifteen-fifteen-fi *
0 00:16:00:00:00:00 192.168.1.4 sixteen-sixteen-sixt *
0 00:17:00:00:00:00 192.168.1.17 seventeen-seven 01:00:09:00:00:00:00
0 00:18:00:00:00:00 192.168.1.018 eighteen-eig 01:00:09:00:00:00:00
0 00:19:00:00:00:00 192.168.1.019 nineteen-ninet *
0 00:20:00:00:00:00 192.168.1.020 twenty-twenty-twe 01:00:09:00:00:00:00
0 00:21:00:00:00:00 192.168.1.021 twentyone 01:00:09:00:00:00:00
0 00:22:00:00:00:00 192.168.1.22 twentytwo-twentytwo 01:00:09:00:00:00:00
0 00:23:00:00:00:00 192.168.1.6 twentythree-twentyt 01:00:09:00:00:00:00
0 00:24:00:00:00:00 192.168.1.24 twentyfour-twentyfo 01:00:09:00:00:00:00
0 00:25:00:00:00:00 192.168.1.25 twentyfiv *
0 00:26:00:00:00:00 192.168.1.26 twentysix-twenty 01:00:09:00:00:00:00
0 00:27:00:00:00:00 192.168.1.27 twentyseven-twent 01:00:09:00:00:00:00
0 00:28:00:00:00:00 192.168.1.28 twentyeigh 01:00:09:00:00:00:00
0 00:29:00:00:00:00 192.168.1.29 twentynine-twentyn 01:00:09:00:00:00:00
0 00:30:00:00:00:00 192.168.1.30 thirty-thirty-thir 01:00:09:00:00:00:00
0 00:31:00:00:00:00 192.168.1.31 thirtyone-thirty 01:00:09:00:00:00:00
1707029378 00:32:00:00:00:00 192.168.1.32 thirtytwo-t 01:00:09:00:00:00:00
0 00:33:00:00:00:00 192.168.1.33 thirtythre 01:00:09:00:00:00:00
0 00:34:00:00:00:00 192.168.1.4 thirtyfour-t 01:00:09:00:00:00:00

实际上是您的输入格式,那么这也将每秒一次调用 6 个租约:logger

$ cat tst.sh
#!/usr/bin/env bash

dhcp_leases='/tmp/dhcp.leases'

WrtPresenceDhcp() {
    awk -v maxLeases=6 -v OFS=';' '
        NF {
            lease = $2 OFS $3 OFS $4
            leases = (numLeases++ ? leases "|" : "") lease
            if ( numLeases == maxLeases ) {
                print leases
                numLeases = 0
            }
        }
        END {
            if ( numLeases ) {
                print leases
            }
        }
    ' "$dhcp_leases"
}

while IFS= read -r leases; do
    echo logger -t "wrtdhcpleasesreport" "$leases"
    sleep 1
done < <(WrtPresenceDhcp)

$ ./tst.sh
logger -t wrtdhcpleasesreport 00:01:00:00:00:00;192.168.1.01;one-one-one-oneo|00:02:00:00:00:00;192.168.1.02;Two-two-twoo|00:03:00:00:00:00;192.168.1.003;three-three-thr|00:04:00:00:00:00;192.168.1.04;four-four-four-fou|00:05:00:00:00:00;192.168.1.005;five-five-fiv|00:06:00:00:00:00;192.168.1.006;six-six-s
logger -t wrtdhcpleasesreport 00:07:00:00:00:00;192.168.1.07;seven-seven-sevenn|00:08:00:00:00:00;192.168.1.008;eight-eight-e|00:09:00:00:00:00;192.168.1.09;nine-nine-ninenin|00:10:00:00:00:00;192.168.1.10;ten-ten-ten-t|00:11:00:00:00:00;192.168.1.011;eleven-eleven|00:12:00:00:00:00;192.168.1.12;twelve-twelve-twe
logger -t wrtdhcpleasesreport 00:13:00:00:00:00;192.168.1.13;thirteen-thirte|00:14:00:00:00:00;192.168.1.14;fourteen-fourteen|00:15:00:00:00:00;192.168.1.015;fifteen-fifteen-fi|00:16:00:00:00:00;192.168.1.4;sixteen-sixteen-sixt|00:17:00:00:00:00;192.168.1.17;seventeen-seven|00:18:00:00:00:00;192.168.1.018;eighteen-eig
logger -t wrtdhcpleasesreport 00:19:00:00:00:00;192.168.1.019;nineteen-ninet|00:20:00:00:00:00;192.168.1.020;twenty-twenty-twe|00:21:00:00:00:00;192.168.1.021;twentyone|00:22:00:00:00:00;192.168.1.22;twentytwo-twentytwo|00:23:00:00:00:00;192.168.1.6;twentythree-twentyt|00:24:00:00:00:00;192.168.1.24;twentyfour-twentyfo
logger -t wrtdhcpleasesreport 00:25:00:00:00:00;192.168.1.25;twentyfiv|00:26:00:00:00:00;192.168.1.26;twentysix-twenty|00:27:00:00:00:00;192.168.1.27;twentyseven-twent|00:28:00:00:00:00;192.168.1.28;twentyeigh|00:29:00:00:00:00;192.168.1.29;twentynine-twentyn|00:30:00:00:00:00;192.168.1.30;thirty-thirty-thir
logger -t wrtdhcpleasesreport 00:31:00:00:00:00;192.168.1.31;thirtyone-thirty|00:32:00:00:00:00;192.168.1.32;thirtytwo-t|00:33:00:00:00:00;192.168.1.33;thirtythre|00:34:00:00:00:00;192.168.1.4;thirtyfour-t

选项 3

如果您的输入与上面的选项 1 所示相同,但您希望输出与上面选项 2 所示的输出相似,那么这也将同时调用 6 个租约,每秒一次:logger

$ cat tst.sh
#!/usr/bin/env bash

dhcp_leases='/tmp/dhcp.leases'

WrtPresenceDhcp() {
    awk -v maxLeases=6 -v OFS=';' '
        { gsub(/^[[:space:]]+|[;[:space:]]+$/,"") }
        $1 == "lease"    { ip = $2 }
        $1 == "hardware" { mac = $3 }
        $1 == "client-hostname" {
            gsub(/^[^"]+"|"[^"]*$/,"")
            host = $0
        }
        $1 == "}" {
            lease = mac OFS ip OFS host
            mac = ip = host = ""
            leases = (numLeases++ ? leases "|" : "") lease
            if ( numLeases == maxLeases ) {
                print leases
                numLeases = 0
            }
            next
        }
        END {
            if ( numLeases ) {
                print leases
            }
        }
    ' "$dhcp_leases"
}

while IFS= read -r leases; do
    echo logger -t "wrtdhcpleasesreport" "$leases"
    sleep 1
done < <(WrtPresenceDhcp)

$ ./tst.sh
logger -t wrtdhcpleasesreport 00:00:00:00:00:00;192.168.20.4;examle-workstation1|00:00:00:00:00:00;192.168.20.5;|00:00:00:00:00:01;192.168.20.6;examle-workstation2|01:00:00:00:00:00;192.168.20.7;|00:00:00:00:00:00;192.168.20.4;examle-workstation1|00:00:00:00:00:00;192.168.20.5;
logger -t wrtdhcpleasesreport 00:00:00:00:00:01;192.168.20.6;examle-workstation2|01:00:00:00:00:00;192.168.20.7;

对于上面的所有选项,在 awk 输出中,我将带有 s 的租约和带有 s 的租约中的字段分开,因为这看起来像是您想要的问题中的某些文本块。显然只是删除以实际调用.|;echologger

如果您尝试做的事情不是上述情况之一,请编辑您的问题以澄清。

评论

0赞 dckiller 11/7/2023
我回家后会测试。选项 2 是最合适的。但是循环必须在文件的 x 行末尾停止。之后,其他的很有趣,因为你向我展示了还有其他的dhcp.leases。我的目标仍然是与家庭助理社区分享,并且必须保持易于适应每个人的习惯。
0赞 Ed Morton 11/7/2023
我不知道“家庭助理社区”是什么意思,也不知道您与他们分享的目标与解决方案有什么关系,但正如我所提到的,如果我的答案中的这些选项都不是您想要的,那么请编辑您的问题以说明您想要什么。请尝试通过声明“这是示例输入”来简化和澄清它,然后显示它,然后说“这是预期的输出”,然后显示它。正如你希望在我的回答中看到的那样,做任何你想做的事情并不难,但首先你必须能够清晰简单地告诉我们那是什么。
0赞 Ed Morton 11/7/2023
关于 - 好吧,这也是微不足道的,但我不相信你之前没有提到过任何关于这一点的事情,你必须在你的问题中告诉我们如何确定在哪一行停下来(行号?空行?那行上的一些字符串?其他东西?)。But the loop must stop at the end of x lines of the file.
0赞 Ed Morton 11/7/2023
关于 - 这是你以前没有提到的其他事情,需要更新你的问题以说明这意味着什么(你希望其他人能够编辑你的代码?有一个配置文件?提供参数?其他东西?,它对你寻求帮助的问题真的重要吗,或者它只是更不相关的文本?)。must remain easily adaptable for everyone
0赞 dckiller 11/7/2023
必须保持易于适应每个人的 = 最终项目。但是循环必须在文件的 x 行末尾停止 = 我想我误导了你。我会在评论之前进行测试。我的意思是,循环不能无休止地绕圈子。Homeassistant = 免费的家庭自动化软件。
0赞 dckiller 11/7/2023 #2

非常感谢大家。这部分代码运行良好,符合我的期望。

解决方案 1:(选择每行的设备数)

#!/bin/bash

dhcp_leases='/tmp/dhcp.leases'

WrtPresenceDhcp() {
    awk -v maxLeases=10 -v OFS=';' '
        NF {
            lease = $2 OFS $3 OFS $4
            leases = (numLeases++ ? leases "|" : "") lease
            if ( numLeases == maxLeases ) {
                print leases
                numLeases = 0
            }
        }
        END {
            if ( numLeases ) {
                print leases
            }
        }
    ' "$dhcp_leases"
}

dumpWrtPresenceDhcp ()
{
    while IFS= read -r leases; do
        echo "$leases" | logger -t "wrtdhcpleasesreport"
        sleep 1
    done < <(WrtPresenceDhcp)
}

dumpWrtPresenceDhcp

exit 0

解决方案 2:(选择每行的字符数)

</tmp/dhcp.leases awk '
    { $0 = $2";"$3";"$4"|" }
    (t+=length())>960 { print "\n"; t=length }
    { print }
    END { print "\n" }
' ORS='' |
logger -t wrtdhcpleasesreport

这两种解决方案都符合我的期望。第一个,对于我的个人文件,生成 4 行,第二个生成 2 行。

@Ed Morton @jhnc再次感谢您的建议。

评论

1赞 dckiller 11/9/2023
对不起,我首先提出了这一点。我以为我可以同时检查两者,但我错过了分数。我还不熟悉这个网站。我还没有完成我的项目,但我昨天已经在我的自述文件中提到了你。我的项目
1赞 jhnc 11/7/2023 #3

您已将我的评论代码添加到您的问题中,但省略了 ,因为您说您没有它。但是,这会破坏代码 - 是拆分为较短行的部分:fmtfmt

</tmp/dhcp.leases awk '{print $2,$3,$4}' OFS=';' ORS='|\r' |
fmt -960 |
tr -d '\r' |
logger -t wrtdhcpleasesreport

有许多替代方法可以近似于 的行为。fmt

例如,只需:awk

</tmp/dhcp.leases awk '
    { $0 = $2";"$3";"$4"|" }
    (t+=length)>960 { print "\n"; t=length }
    { print }
    END { print "\n" }
' ORS='' |
logger -t wrtdhcpleasesreport

评论

1赞 jhnc 11/7/2023
@EdMorton既然 6 拟合,我假设单个数据集也可以
1赞 Ed Morton 11/7/2023
awk 脚本中有一个不太可能的下雨天情况 - 如果第一条记录的长度超过 960 个字符,它将打印一个空行。也许长度测试应该在它之后而不是之前进行(但随后您需要测试“\n”是否刚刚打印)。printEND
1赞 jhnc 11/7/2023
@EdMorton值得注意的,但如果发生这种情况,编写代码的整个前提需要重新思考,因为会导致记录器的输出过长
1赞 jhnc 11/7/2023
@EdMorton顺便说一句,我在打印前测试了长度,否则发出的每一行都可能太长。可以通过检查来避免开始时的空白,但我认为这里没有必要。NR>1
1赞 dckiller 11/8/2023
@jhnc我用 fmt 测试了第一个解决方案。-ash:fmt:未找到。我得出结论,我的系统没有这个选项。.第二个我有一个错误。awk: cmd. line:3: 意外的令牌。platform BusyBox v1.36.1