Можно ли отображать разное содержимое в разных файлах, созданных в диапазоне bash for loop? - PullRequest
0 голосов
/ 30 октября 2018

Я пытаюсь создать скрипт с именем 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 всем файлам. Кто-нибудь знает, что я делаю неправильно, или вы можете указать мне правильное направление? Заранее спасибо.

Я прошу прощения, если об этом уже спрашивали, но я попытался найти решение, и ничего похожего на мой сценарий не появляется. Обычно в сообщениях цикл записи диапазона записывается в один файл, и здесь я хочу создать несколько файлов из цикла диапазона. Возможно, я не использую правильную терминологию при поиске, но любая помощь будет принята с благодарностью. Пожалуйста, не наказывайте меня, если этот вопрос уже был задан. Если это так, пожалуйста, дайте мне знать, и я могу удалить пост или переместить его, если необходимо.

С уважением,

смиренно преданный ученик

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Нет необходимости в любом цикле, если вы используете printf.

Кроме того, если вы хотите разделить содержимое на основе некоторого количества строк, используйте команду split.

printf "192.168.10.1%02d\n" {0..14} | 
  split --lines=5 --suffix-length=1 --additional-suffix=.txt \
        --numeric-suffixes=1 - list
0 голосов
/ 30 октября 2018
  1. Он будет записывать одно и то же для всех файлов, потому что вы не меняете то, что пишете внутри цикла, в зависимости от того, в каком файле вы находитесь. Он расширяет фигурные скобки независимо и полностью в каждой строке; единственная причина, по которой эти три файла создаются отдельно, заключается в том, что первое такое расширение является частью условия инициализации цикла 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
    
  2. Вы видите только последнее, что написано, потому что вы используете >, который перезаписывает весь файл. Если вы собираетесь перенаправлять каждую строку отдельно, вам следует использовать >>, который добавляется в конец файла, не стирая то, что уже есть.

Но было бы проще просто использовать пару вложенных циклов подсчета и некоторую математику и перенаправить весь внутренний цикл в файл в виде одного перенаправления, которое все еще может использовать >:

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. Я не уверен, почему вы записываете backspace в начало каждой строки вашего текстового файла IP-адресов; если вы уроните его, вы можете использовать только echo 192.168.1.$b.

В ответ на ваш комментарий о переходе за 255: если вы хотите выполнять арифметику с IP-адресами, я бы подумал об использовании чего-то другого, кроме оболочки и ее встроенных арифметических функций. Вероятно, в вашем дружественном окружном менеджере пакетов есть ряд специальных инструментов для управления 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
...