【问题标题】:How can I more efficiently create a unique or incremental name within this bash for loop?如何在此 bash for 循环中更有效地创建唯一或增量名称?
【发布时间】:2020-01-08 17:41:32
【问题描述】:

以下代码作为 cronjob 运行以检索和保存 IP 列表,将文件拆分为 2,并将 2 个文件中的每一个加载到 2 个 ipset 中。该列表被拆分,因为它超过 65,535 行。该代码有效,但它很丑陋,我很感激一些关于如何使它更好/更清洁/更快的反馈。

#!/bin/bash
curl -s "https://example.com/files/list.ipset" > /tmp/ipset.txt
TOTAL_LINES=$(wc -l </tmp/ipset.txt)
((LINES_PER_FILE=(TOTAL_LINES+2-1)/2))
split --lines=${LINES_PER_FILE} /tmp/ipset.txt /tmp/setsplit.
for f in /tmp/setsplit.*; do
        x="$(echo $f | sed 's/\/tmp\/setsplit\.//g')"
        iptables -t mangle -D PREROUTING -m set --match-set "$x" src,dst -j DROP
        ipset destroy "$x"
        ipset create "$x" hash:ip
        while read LINE; do ipset add "$x" $LINE; done < "$f"
        iptables -t mangle -I PREROUTING -m set --match-set "$x" src,dst -j DROP
done
rm -rf /tmp/setsplit.* /tmp/ipset.txt

我主要关心的是变量 x 的创建方式。 Split 创建以下文件,for 循环会对其进行迭代:

/tmp/setsplit.aa

/tmp/setsplit.ab

有没有更好的方法使用 $f 的“aa”和“ab”部分作为 ipset 名称,而不是使用 echo/sed 创建变量 x?或者更好的是,带有数字增量的基本名称,例如:ipset destroy ListX 其中 X 是 for 循环处理的每个文件的唯一编号?

【问题讨论】:

    标签: bash for-loop while-loop iptables


    【解决方案1】:
    $ echo "$f"
    /tmp/setsplit.aa
    $ echo "${f##*.}"
    aa
    

    ## 运算符从 f 的扩展中删除匹配 *. 的最长前缀(即直到并包括最后一个 . 的所有内容)。

    【讨论】:

      【解决方案2】:

      @chepner 展示了获取f 后缀的“正确”方式:

      x=${f##*.}
      

      这可以在bashman页面的“参数扩展”部分找到。

      至于您的其他问题,是的,拆分命令可以生成编号序列而不是字母。这是在split man 页面上。选项-d。也可以更改后缀的大小,选项-a。

      我不认为放缓是因为这些。

      【讨论】:

        猜你喜欢
        • 2021-10-08
        • 2013-01-27
        • 2014-11-24
        • 1970-01-01
        • 2018-09-10
        • 1970-01-01
        • 1970-01-01
        • 2015-12-26
        • 1970-01-01
        相关资源
        最近更新 更多