Разделение имен переменных из строк вывода без пробелов

У меня есть следующий фрагмент кода, в котором я намерен:

Итереть 5 раз петлю;
получить строку из файла (для каждой итерации мне нужна следующая строка);
используйте строку как заголовок для файла;
поставьте временную метку в начале ее;
используйте строку в качестве аргумента для ping; распечатать некоторые предложения, информирующие пользователя о ходе выполнения кода;

Итерация уже работает.
Если я пропущу часть sed, все работает, но я запускаю ping 5 раз против той же цели.
Каждая строка файла hosts.txt имеет один IP-адрес, который я намерен выполнить ping.

for ((i>=1;i<=5;i++)) do sed -n "$ip" hosts.txt | read output touch "$output.txt" date >> "$output.txt" printf "\nComeçando o teste de $output." printf "\nTeste em andamento." ping -c 10 -i 1 "$output" >> "$output.txt" done 

Я считаю, что проблема в том, что я делаю что-то неправильно в синтаксисе sed. Если я попытаюсь использовать bash непосредственно sed -n 1p hosts , я получаю первую строку. Но поскольку мне нужно, чтобы это число было $ i, если я ставлю $ i прямо перед тем, как p bash интерпретирует ip как переменную вместо переменной i плюс аргумент p после нее.

Как я могу исправить это поведение и не испортить эту вещь снова?

3 Solutions collect form web for “Разделение имен переменных из строк вывода без пробелов”

Я предполагаю, что вы используете bash, так что это должно работать лучше:

 for ((i=1;i<=5;i++)) do sed -n "$ip" hosts.txt | ( read output touch "$output.txt" date >> "$output.txt" printf "\nComeçando o teste de $output." printf "\nTeste em andamento." ping -c 10 -i 1 "$output" >> "$output.txt" ) done 

Проблема, которую вы испытывали, – bash , как и большинство интерпретаторов интерпретатора оболочки вне ksh помещают все компоненты конвейера в подоболочку, поэтому output переменная сразу теряется после установки.

Также обратите внимание, что я исправил цикл for который, как написано, имел неопределенное поведение, поскольку переменная i не была инициализирована.

Проблема в том, что, как вы заметили, i и ip являются допустимыми именами переменных. Поэтому, если вы хотите использовать значение $i за которым следует символ p , вы можете использовать гибкие фигурные скобки, чтобы четко разграничить, где начинается и заканчивается имя переменной:

 sed -n "${i}p" hosts.txt | read output 

Несколько более простым решением является

 for ((i=1; i<=5; i++)) do read output date >> "$output.txt" printf "\nComeçando o teste de %s." "$output" printf "\nTeste em andamento." ping -c 10 -i 1 "$output" >> "$output.txt" done < hosts.txt 

Обратите внимание на < hosts.txt в конце последней строки после done . Это открывает hosts.txt один раз и просто считывает первые пять строк из него. Как упоминалось don_crissti, делаю sed … hosts.txt | read output sed … hosts.txt | read output в цикле означает, что вы читаете файл hosts.txt пять раз. Поскольку read output параллелен остальной части цикла (не в конвейере), остальная часть кода в цикле будет иметь доступ к значению output считанного из файла. Кроме того (как указывал дон), вам не нужно touch ; command >> file создаст file если он еще не существует.

Обратите внимание, что если один из ваших файлов hostname .txt вашего hostname .txt уже существует, этот код добавит к нему новую информацию. Если вы хотите отбросить старые данные и начать с нуля, date > "$output.txt" вместо date >> "$output.txt" .

Будьте осторожны с передачей неизвестных данных непосредственно в printf . В случае (маловероятно?), Что у одного из ваших «имен хостов» есть % в нем, ваш код будет искажать это имя. Лучше передавать внешние данные в %s (для печати строки).

Вы не говорите, хотите ли вы читать только первые пять строк файла hosts.txt а затем останавливаться или хотите прочитать весь файл, и вам известно, что это пять строк. Если вы хотите прочитать весь файл, просто выполните

 while read output do date >> "$output.txt" printf "\nComeçando o teste de %s." "$output" printf "\nTeste em andamento." ping -c 10 -i 1 "$output" >> "$output.txt" done < hosts.txt 

Когда вы дойдете до конца файла, инструкция read output завершится с ошибкой, и цикл завершится.

  • Создание сценария оболочки на рабочем столе и получение запроса?
  • Bash: Имея 2 файла, как я могу проверить, появляется ли второе имя в первом случае во втором
  • Заменить второе вхождение строки
  • как передать пароль двух серверов в оболочке
  • как объявить переменные командной строки в сценариях оболочки?
  • обработка ошибок runuser
  • Как использовать вывод команды для процесса в цикле в Bash?
  • сравнение двух файлов по строкам
  • Как найти процесс с максимальными файловыми дескрипторами?
  • найти определенный шаблон строки из файла в Unix Shell Scripting
  • Записывать команды только в файл
  • Interesting Posts

    Как остановить курсор от мигания

    Передача файла Tftp через последовательный порт

    Открыть список файлов в vim для определенных строк

    Как получить доступ к логину через ssh, когда пароль не установлен?

    Поиск всех файлов с помощью ack

    Логротат ведет себя неожиданно

    Поддерживает ли конфигурация iscsi target и инициатор iscsi в двух Linux-узлах и использование Ethernet-кабеля для связи делает его SAN?

    установка квоты на zfs не работает

    Строки печати, если заданный столбец начинается с заглавной буквы

    Как бы вы назначили разрешения только для чтения для запуска ls -l / proc / {pid} / fd для процессов, которые у вас нет?

    Плохое разрешение TTY с драйвером nVidia

    Как отобразить Thunderbird в меню

    Является ли система полностью бездействующей при загрузке с параметром ядра INIT = / bin / sh, а затем немедленно выйти из оболочки?

    В чем разница между && и; при разрыве сна на фоне?

    java.lang.UnsatisfiedLinkError: libawt_xawt.so: libXi.so.6: невозможно открыть файл общих объектов: нет такого файла или каталога

    Linux и Unix - лучшая ОС в мире.