Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Вывести попеременно введенную строку и по 2 строки из файла

Здравствуйте, уважаемые форумчане! Доброго вам времени суток! =)

Возник у меня вопрос по shell-у. Пишу shell-процедуру, которая:
1) вводит символьную строку, содержащую два целых числа m и n, разделенных пробелами.
2) читает содержимое файла, передаваемого в качестве первого параметра.
3) выводит на экран каждые m секунд попеременно n строк из файла и пустую строчку.

С помощью данного форума написал почти все =) Получилось так:

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# Program, Variant 37
 
# Проверим количество аргументов, переданных в процедуру.
# --------------------------------
 
# Если количество аргументов, переданных в процедуру, не равно 1...
if [ $# -ne 1 ]; then
 
# Выведем ошибку на экран.
echo 'Error count of arguments! Try again!'
 
# Выход с кодом ошибки.
exit
 
fi
# -------------------------------
 
# Ввод параметров в символьной строчке.
# -----------------------------
 
# Вывод приглашения без перевода строчки.
echo -n "Enter numbers M and N:  "
 
# Ввод строчки в переменную s
read s
 
# Составляем массив из строки. Пробелы заменяются на пробелы.
# Элементы массива разделяются по пробелу.
nums=(${s// / })
 
# Для отладки - вывести элементы массива.
echo ${nums[0]}, ${nums[1]}
 
# -----------------------------
 
# Основной цикл программки.
 
while true; do
 
flines=$(head -${nums[1]} $1)
 
echo $flines
 
sleep ${nums[0]}
 
echo
 
done
 
echo $0
И возник вопрос- как мне вывести не просто первые N строчек из файла, а постоянно каждые следующие N? Ну например, пусть в файле есть строчки:

-1
-2
-3
-4
-5
-6
-7
-8
-9
-10
И пусть N = 2.
Мне надо, чтобы из файла каждые три секунды выводилось эти строчки по две:

-1
-2
...
-3
-4
...
Не получается =)) Помогите, пожалуйста =))

Заранее всем спасибо!

P.S.
И , если будет время, объясните, пожалуйста, как работает строчка:

Bash
1
nums=(${s// / })
Ответ: вот мой код,который верно работает
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
if [ -e $1 ]                            #проверка существования файла
then                                    #если файл существует
  echo "Введите строку"                 #приглашение к вводу
  read str                              #читаем строку
  file=$1                               #открываем файл
  if [ $str -gt 0 ] || [ $str -lt 1 ]   #проверка, являеся ли строка числом
        #если не является, то вернёт ошибку и вызовет блок else, если
        #если являеься, то неравенство всегла вернёт 1 ( < 1 or > 0 )
  then                                  #строка является числом
  while true                            #бесконечный цикл считывания из файлоа
  do
    while read line                     #вложенный конечный цикл, считывание
    do                                  #происходит, пока это возможно
      echo $line                        #вывели строку считанную в while read
      read line                         #считали следующую строку
      echo $line                        #вывели её
      echo $str                         #вывели строку, введённую с клавиатуры
      sleep 6                           #задержка 6 секунд
    done < $file                        #цикл считывает строки из файла
     sleep 6                           #задержка 6 секунд
    done < $file                        #цикл считывает строки из файла
  done                                  #конец основного бесконечно цикла
  else                                  #случай некорректной строки
    echo "Некорректная строка"          #выводим сообщение
  fi
else                                    #случай некорректного файла
  echo "Файл не существует"
fi
Вопрос: Импортировать внешние данные в бесконечный цикл

Привет, есть скрипт, который сканирует подсети по указанным портам.
Считывает массивы из тела скрипта.
И загоняет полученные данные в бесконечный цикл while:; и спокойно там работает и все нормально.
Но когда добавляются или подсети или порты, их необходимо перечитать, но как это передать не останавливая работу скрипта?
Массивы и переменные можно вынести через source /путь/к/файлу.sh, так делал уже не помогает.


Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/bin/bash 
 
Scan_types=(internal external)
 
internal="21,22"
external="20,23"
 
reports_dir="/tmp/report"
 
maximum_subnet_size=24
Subnets=(
192.168.1.0/31
192.168.1.0/32
192.168.1.0/29
)
 
...
...
...
 
function do_scan()
{
while :;
do
   sleep 3
   for target in ${Targets[@]}
   do
...
...
...
     sudo nmap -n -T4 --privileged --open  -p$1 -sS -sV -Pn $target 2>/dev/null
   done
 
done
}
 
 
for ((i=0; i<=$((${#Scan_types[@]}-1)); i++));
do
    sleep 2
    ports=${Scan_types[$i]}
    pid_index=$i
    (do_scan ${!ports} $pid_index) &
done
Ответ: Все там нормально с логикой, типы сканов могут добавляться.
А цикл делает столько раз, сколько в типах сканов перечислено имен и отдает в бесконечный цикл и там все уже сканится беснечно долго.

Добавлено через 5 часов 47 минут
Все сделал, два варианта. разбил на две функции и другой.
Вопрос: Сравнение размеров файлов

Всем привет!
Подскажите, как сравнить файл(размер и название которого уже записаны в переменную) с другими файлами в указанной директории. То есть сравнить их размеры и вывести в отдельный текстовый документ.

Bash
1
2
3
4
5
cd /e/Test/1
file1=$(dir -S -r | awk '{print $1}')
filesize1=$(wc -c $file1 | awk '{print $1}')
mv $file1 /e/Test/2
cd /e/Test/2
Тут две директории и в первой я нахожу файл с наименьшим размером, записываю его данные в переменные и перемещаю в другую директорию, в которой я должен сравнить его размер с другими размерами файлов
Заранее спасибо!
Ответ: N9wKa, Вы записали в переменную filesize размер тестируемого файла
а теперь в цикле мы вычисляем размеры каждого файла size из второй директории и сравниваем их
Тоесть size это временная переменная для хранения текущего размера каждого файла
Вопрос: Программа записи в файл bash

Разработать программу записи в файл из вводимой с клавиатуры последовательности чисел,
лишь тех, которые входят в диапазон, заданный с клавиатуры.
Имя файла задаётся пользователем в командной строке.
Если оно не задано, создать файл в домашнем каталоге пользователя с названием Numbers.txt.
При наличии такого файла – дописывать в него данные с новой строки.
Надо написать на bash.
Сделал на С++, но проблемы с переводом на bash.
Код C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <fstream>
 using namespace std;
int main(int argc, char*argv[])
{
setlocale (0,"RUS");
    int a, b, c, i = 0;
    char outfile[BUFSIZ] = { 0 };
    ofstream ofile;
 
    cout << "Введите начало диапазона: ";
    cin >> a;
    cout << "Введите конец диапазона: ";
    cin >> b;
    if (a > b) cout << "Неверный ввод (a > b)!" << endl, exit(1);
 
    if (argc != 1) strcpy(outfile, argv[1]);
 
    if (!*outfile)
    {
        strcpy(outfile, "Numbers.txt");
    }
 
    ofile.open(outfile);
 
    do
    {
        cout << "Введите число: ";
        cin >> c;
 
        if (c <= b && c >= a) ofile << c << " ";
        i++;
    } while (i != 10);
    ofile.close();
    system ("pause");
    return 0;
}
Ответ: Пока значение а (которое поочередно принимает значения start end) не будет числом вызывается процедура из 2-х команд: вывод на экран сообщения "start( или end) should be a number" и приглашения "Range start( или end):" с сохранением ввода пользователя в переменную start( или end)
P.S. Вы думаете отступы просто так ставятся? Это для наглядности, где какой цикл начинается и заканчивается (а так я всё в 1 строчку могу написать)
Вопрос: Переименование файлов в цифры

Написал скрипт для замены имен файлов в каталоге на цифры 1,2,3 и т.д
Не могу исправить один недочёт,если в имени файла есть пробелы или другие символы,скрипт файл не переименовывает
Может кто знает в чём ошибка
Bash
1
2
3
4
5
6
#!/bin/bash
nname=0;
for name in $(ls);
do let nname+=1;
mv $name $nname;
done
Ответ:
Bash
1
2
3
4
for name in * ; do #использовать ls в цикле — не лучшая идея
    mv "$name" $((++nname)) #заключать путь в кавычки — правильно
                            #+(()) — использование арифметических действий в bash позволяет
                            #+значительно упростить код
Вопрос: Ошибка синтаксиса неожиданный конец файла

Добрый вечер! пытаюсь написать скрипт на bash чтобы определял количество слов начинающихся на заданную букву. Реализовала ввод слов в массив word и попробовала чтобы вывел все слова массива. Программа отрабатывает но слова не выводятся. Выводит ошибку про неожиданный конец файла

Bash
1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
declare -a words #объявление массива
echo "Введите слова для обработки (разделяя их пробелами)."
read -a words 
echo "Количество слов в массиве: ${#words[*]}"
element_count=${#words[@]}
index=o
while ["index" -lt "$element_count"]
 do
  echo ${words[$index]}
  let "$index = $index+1"
done #Ошибка синтаксиса неожиданный конец файла
Может есть и другие ошибки но я не вижу их, убунту ругается только на конец файла. Подскажите пожалуйста, в чем может быть дело?
Ответ: HAMAHA, еще раз - не нужен там цикл.
Bash
1
2
3
4
5
6
7
#!/bin/bash
declare -a words
read -p 'Введите слова через пробел: ' -a words
read -p 'Укажите букву для поиска  : ' c
echo "Всего слов в массиве      : ${#words[@]}"
found=$(echo "${words[@]}" | grep -oi "\b${c}\w*")
echo -e "$found\n----------\nВсего совпадений: $(echo $found | wc -w)"
Вопрос: Массовая проверка IP из текстового файла

Здравствуйте!
Требуется помощь новичку.
Есть +1000 айпишников в текстовом файле, каждый с новой строки. Необходимо проверить все по очереди в whois, результаты проверки также сохранить в текстовый файл. Возможно это сделать при помощи bash-скрипта?
Направьте, как лучше это осуществить.
Ответ: Значит попробуйте через цикл:
Код Bash
1
2
3
4
while read -r address
do
    whois "$address"
done < ip_file.txt > result.txt
Вопрос: Цикл While

Код Bash
1
2
3
echo -n "Enter command: "
read cmd
chmod $cmd $fname
Как сделать цикл while, чтобы был запрос: " «Продолжить работу? (да/нет)»
Если – да, то действия повторяются."
Можно конечно не через while, самое главное чтобы работало и лижбы не работало через функцию
Ответ: Подскажите пожалуйста, задача следующая:
Написать цикл, который выведет все понедельники этого года в формате ММ-ДД
Только сделать это надо скорее всего через цикл for
и понадобится команда date
Но до меня не доходит как это можно сделать.

Добавлено через 1 час 46 минут
Вообщем я сам додумался. Если кому интересно, то вот код.
Код Bash
1
for i in {1..52}; do date --date="monday $i week `date +%V` week  ago " +%m%d ; done
Вопрос: Рекурсивная функция для подсчета файлов в данном каталоге

Такое дело, нужно написать программу для подсчета файла в данном каталоге и если в этом каталоге есть подкаталоги , то в них тоже считать отдельно. Код написал, но чет ошибка выскакивает... Подскажите что не так. Заранее спасибо
Код Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash
findContent() {
 count=0;
 for file in $1/*
 do
 if [ -d "$file" ]
 then
 echo $file
 findContent "$file"
 else
 count=$(($count+1))
 fi
 done
 if [ $count -ne 0 ]
 then 
 echo $count
 fi
 count=0;
 }
 dir=~/N
 findContent $dir
Ответ: Если выводить по каждой директории, то больше подходит вариант топикстартера (ну доработанный конечно)
Код Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
file_cnt() { 
local count=0
local dir="${1:-"."}"
for item in "$dir"/*
do
    if [ -f "$item" ]
    then
        count=$(($count + 1))
    elif [ -d "$item" ]
    then
        file_cnt "$item"
    fi
done
echo "${dir}: $count"
}
Да, и если пробелы в именах
Код Bash
1
for dir in `find "$START" -type d`
будет выдавать ошибку. В таких случаях лучше использовать конструкцию
Код Bash
1
while IFS="" read -r dir ; do ... done < <(for dir in find "$START" -type d)
Добавлено через 12 минут
Но если хотите find можно обойтись без циклов
Код Bash
1
find -type d -printf '%p : ' -exec bash -c 'find {}/* -prune -type f | wc -l' \;
Вопрос: Определить тип файлов передаваемых как аргументы с контролем их количества

Доброго времени суток!
Мне требуется помощь в написании скрипта,который может принимать несколько параметров (от 1 до 8) и для каждого из них определять тип файла (каталог,символическая ссылка, исполняемый, обычный, прочий, не существует) Если параметры при запуске отсутствуют, скрипт должен сообщить о необходимости наличия параметров и закончить работу. Если же параметров больше 8, сообщить о слишком большой количестве параметров и закончить работу. Для отладки использовать echo.

Буду очень счастлива если поможете!
Ответ: Количество параметров — системная переменная $#
Закончить работу — команда exit
Oпределить тип — команда file
Перебрать аргументы — цикл for arg ; do … ; done