我正在尝试创建一个名为create.ip.list.txt.sh
的脚本
运行时,我希望输出如下:
[root@ubuntu]$ head li*
==> list1.txt <==
192.168.1.100
192.168.1.101
192.168.1.102
192.168.1.103
192.168.1.104
==> list2.txt <==
192.168.1.105
192.168.1.106
192.168.1.107
192.168.1.108
192.168.1.109
==> list3.txt <==
192.168.1.110
192.168.1.111
192.168.1.112
192.168.1.113
192.168.1.114
这是我到目前为止拥有的脚本:
#!/bin/bash
i=1
for i in list{1..3}.txt; do
echo -e -n "\b192.168.1.10"{0..4}"\n" > $i
echo -e -n "\b192.168.1.10"{5..9}"\n" > $i
echo -e -n "\b192.168.1.1"{10..14}"\n" > $i
done;
但是当我运行代码时,这是我得到的输出:
[root@ubuntu]$ head li*
==> list1.txt <==
192.168.1.110
192.168.1.111
192.168.1.112
192.168.1.113
192.168.1.114
==> list2.txt <==
192.168.1.110
192.168.1.111
192.168.1.112
192.168.1.113
192.168.1.114
==> list3.txt <==
192.168.1.110
192.168.1.111
192.168.1.112
192.168.1.113
192.168.1.114
[root@ubuntu]$
它会循环并根据需要创建单独的文件,但似乎正在将最后一个echo命令回显到所有文件。有人知道我在做什么错吗,或者您可以为我指明正确的方向?预先感谢。
很抱歉,是否已经有人提出这个要求,但是我试图四处寻找解决方案,但没有弹出类似我的情况的信息。通常,帖子将范围循环写入单个文件,在这里我要从范围循环创建多个文件。也许我在搜索时没有使用适当的术语,但是任何帮助将不胜感激。如果已经问过这个问题,请不要惩罚我。如果有,请告诉我,如有需要,我可以将其删除或重新安置。
此致
一个谦虚的学生
答案 0 :(得分:2)
它将对所有文件写入相同的内容,因为您不会根据所在的文件来更改循环内的编写内容。它独立且完全地在每一行上扩展了花括号扩展;分别创建这三个文件的唯一原因是,第一个这样的扩展是for
... in
循环初始化子句的一部分。一旦您查看了卷曲扩展后的代码外观,这可能更有意义:
for i in list1.txt list2.txt list3.txt; do
echo -e -n "\b192.168.1.10"0"\n" "\b192.168.1.10"2"\n" "\b192.168.1.10"3"\n" "\b192.168.1.10"4"\n" > $i
echo -e -n "\b192.168.1.10"5"\n" "\b192.168.1.10"6"\n" "\b192.168.1.10"7"\n" "\b192.168.1.10"8"\n" "\b192.168.1.10"9"\n" > $i
echo -e -n "\b192.168.1.1"10"\n" "\b192.168.1.1"11"\n" "\b192.168.1.1"12"\n" "\b192.168.1.11"13"\n" "\b192.168.1.1"14"\n" > $i
done
您仅看到最后写入的内容,因为您正在使用>
,它将覆盖整个文件。如果您要分别重定向每一行,则需要使用>>
,它会附加在文件末尾,而不会删除已经存在的内容。
但是,仅使用几个嵌套的计数循环和一些数学运算,然后将整个内部循环作为仍可以使用>
的单个重定向重定向到文件,将会更简单:
for i in {0..2}; do # or for (( i=0; i<3; ++i )); do
for j in {0..4}; do # or for (( j=0; j<5; ++j )); do
let b=100+i*5+j
printf '\b192.168.1.%d\n' "$b"
done >list$((i+1)).txt
done
我使用printf
代替了echo -e -n
,因为printf
不仅比bash更简单,而且可移植到更多shell中。不过,我不确定为什么要在IP地址文本文件的每一行的开头写入一个退格键;如果您放弃,则只能使用echo 192.168.1.$b
。
为回应您关于超过255的评论:如果您想对IP地址执行算术运算,我会考虑使用Shell及其内置的算术功能以外的其他功能。友好的社区包管理器中可能提供了许多专用IP操纵工具,但您可以使用可能已经安装的工具,例如Ruby:
ip=192.168.1.250
for i in {0..2}; do
f=list$((i+1)).txt
for j in {0..4}; do
printf '\b%s\n' "$ip"
ip=$(ruby -ripaddr -lpe '$_=IPAddr.new(IPAddr.new($_).to_i+1,2)' <<<$ip)
done >"$f"
done
之后,list2.txt
如下所示:
192.168.1.255
192.168.2.0
192.168.2.1
192.168.2.2
192.168.2.3
答案 1 :(得分:0)
如果使用printf
,则不需要任何循环。
此外,如果您想根据行数分割内容,请使用split
命令。
printf "192.168.10.1%02d\n" {0..14} |
split --lines=5 --suffix-length=1 --additional-suffix=.txt \
--numeric-suffixes=1 - list