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

Код Bash
1
2
expr substr "12003456" 3 2
echo $?
Когда результирующая строка состоит из нулей, код возврата expr равен 1.
Есть где описание этого чуда?

Ман смотрел - ничего не нашёл.
Ответ: Спасибо. Пока носом не ткнули, я эту строку не видел.
Вопрос: Expr index с русскоязычным текстом

Насколько понял, у expr index есть проблемы при работе со строками, если в них есть русскоязычный текст. Для наглядности пример:

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
#! /bin/bash
 
#LINE="Some text,123,more text,456,654,1"
LINE="Какой-то текст, 123,опять текст,456,654,1"
echo "Строка до обработки равана = ["$LINE"]"
echo ========
    for i in 1 2 3
    do
        INDEX=`expr index "$LINE" ,`
        LINE=${LINE:$INDEX}
        echo "Строка после $i круга = ["$LINE"]    ******INDEX=["$INDEX"] (удалено элементов)******"
    done
exit 0
Есть ли способ "научить" expr index понимать русские символы?
Ответ:
Сообщение от ReM
Интересно, пробую разные варианты, это один из них. В защиту этого варианта скажу что он работает, правда при условии что строка будет англицкая
Не спортивно. Английские символы самые однобайтовые.
Вопрос: Cygwin, не работают функции expr и who

Здравствуйте! У меня в версии cygwin не работают функции expr и who. В чем может быть причина?
Ответ:

Не по теме:

А у Вас какая версия?

Вопрос: обьясните строчку и что означает expr ?

Bash
1
a=`expr  $a/* $counter`
там \ такой слэш
Ответ: Это умножение. Экранировано слэшем для блокирования раскрытия пути bash
Вопрос: проверка на принадлежность множеству целых чисел

Доброго времени суток,
у меня есть файл, в нем есть строки (слова), целые числа и десятичные. Подскажите пожалуйста, как сделать проверку на принадлежность к целым числам, чтобы потом можно было работать только с ними. Пробовал через принадлежность множеству элементов и ещё проверял на равенство шаблону, но что-то не так делаю. Помогите пожалуйста.

Добавлено через 1 час 17 минут
Всё, разобрался, если кому интересно:
i - проверяемый элемент

expr $i : '-\?[0-9]\+$' && echo yea || echo not

только если мы проверяем 34,4 - не целое, а если проверяем 34.4 - он ругается, что выражение не правильное
такая же штука со строчками: "string" - не целое, но если на русском: "строка" - пишет ту же ошибку, что и 34.4
Ответ: Для проверки expr не самый лучший инструмент. Если это файл, я бы посоветовал grep:
Bash
1
grep -Po '(^|\s)\K-?[0-9]\b(?![,.]0*[1-9]+)' file
Добавлено через 8 минут
Если все слова|числа идут по 1 в строке — ещё проще
Bash
1
grep -Ex '\-?[0-9]+([.,]0+)?' file
Вопрос: Собрать информацию в файл с 50 серверов

Здравствуйте!
Новичек!
Прошу помочь допилить скрипт.
Задача - собрать информацию с удаленных серверов в один файл (df -h, uptime, lsb_release и т.д.).
В файле aliases 50 строк названий и ip адресов серверов.

Код Bash
1
2
3
4
5
6
7
8
9
10
11
12
dir=/media/info/;
if [ ! -d "$dir" ];
then mkdir -p $dir;
fi;
while read line;
    do
    nchr=`expr index "$line" ' '`
    alias=${line:0:$nchr-1}
    ip=${line:$nchr:`expr length "$line"`}
        ssh root@"$ip" ' uptime > /media/'"$alias"'.txt | exit ';
        scp [email]root@"$ip":/media/"$alias"'.txt[/email]' $dir;
    done <aliases
Цикл отрабатывает только один раз, так как после подключения к удаленному серверу, скрипт не находит файл aliases, т.е. команда exit не отрабатывает, пробовал logout результат одинаковый.
Тэг [email] - самостоятельно проставляется.
Ответ: Немного и оказывается это известный баг. Тут используется перенаправление ввода (<"/media/aliases"), который и считывает while. Однако, некоторые команды, типо ssh, cat и т.д. тоже его считывают, так что уже ничего для while не остаётся. Методов решения как всегда несколько:
1. "Заткнуть пасть" команде чем-нибудь другим, что она не "доедала" стандартный ввод: ssh ... </dev/null
2. Перенаправить ввод строк через другой дескриптор: while read -u9 ... done 9<"/media/aliases"
3. Использовать опции самой программы, если такие есть: ssh -n ...
Код Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
 
dir=~/media/info/
if [ ! -d "$dir" ]
then
    mkdir -p $dir
fi
 
while read srv_name srv_ip
do
    echo "$(date --rfc-3339=seconds) $srv_name"
    ssh -n root@"$srv_ip" 'uptime ; lsb_release -d' 
done <"/full/path/aliases" >"/media/info"
Вопрос: Скрипт для QNX. Поиск файлов по времени

Здравствуйте, мне необходимо составить скрипт, который будет находить не более 100-а файлов, созданных ранее введённой пользователем даты в формате dd:mm:yy.

Я создал этот скрипт, но интерпретатор пишет, что не может открыть: нет такого файла или директории.
Собственно скрипт:

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
51
52
53
54
55
56
57
58
59
60
oldIFS="$IFS"
 
IFS=":"
alrt()
{
x=$1
#x=$(expr $x+1)
if $(expr 100 < $x) // <---- Error
then
echo "Found more 100 files!!!"
rm $buf;
exit 1
fi
}
#Data write
echo -n "Input date in format: dd:mm:yyyy "
read d m y
if test -z $d || test -z $m || test -z $y
then
echo "Failed date!!! Exite!!!"
exit 1
fi
 
IFS="oldifs"
 
#Find
 
buf="buf"
touch buf
touch -t "${y}${m}${d}0000" "$buf"
a=$(find . -type f -newer "$buf" -exec ls '{}' ';')
 
alrt $n
 
if test -z "$a"
then
n=0
fi
if test -z "$1"
then
fn="FIND.TXT"
else
fn=$1
fi
 
if test -f "$fn"
then
echo -n "$fn exist. Rewrite? (y/n): "
read yn
fi
case $yn in
'y' | 'Y' ) echo "$a" > "$fn";;
'n' | 'N' ) echo "$a" >> "$fn";;
* ) echo "$a" >> "$fn";;
esac
echo "$n founded files"
echo "-----------------------------------------" >> "$fn"
echo "$n founded files" >> "$fn"
rm "$buf"
exit 0
Прошу помочь разобраться с этим..Что не так?
Ответ: Но когда я немного изменил опции(добавил: !) :
Bash
1
find . -type f ! -newer "$buf" -exec ls '{}' ';'
Начал выводить ВСЕ файлы. Совершенно без разбора по дате..
Вопрос: Построить арифметическую прогрессию

Здравствуйте.
Стояла задача:
Разработать программу построения арифметической / геометрической прогрессии. Тип прогрессии, шаг и количество элементов вводятся в качестве параметров запуска скрипта.

Решил ее так:
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
#!/bin/bash
typeprog=$1
d=$2
n=$3
i=1
M[0]=1
if [ $typeprog = 'Арифметическая' ]; then
while [ $i -lt $n ];
do
M[$i]=`expr ${M[$(($i-1))]} + $d`
i=$(($i+1))
done
echo 'Арифметическая прогрессия' ${M[@]}
    elif [ $typeprog = 'Геометрическая' ]; then
while [ $i -lt $n ];
do
M[$i]=`expr ${M[$(($i-1))]} \* $d`
i=$(($i+1))        
done
echo 'Геометрическая прогрессия' ${M[@]}
        else
            clear
                echo 'Неверно указан тип прогрессии'
                    exit
                    fi
Преподаватель лабу засчитал, но оставил комментарий "Зачем все эти пляски с массивами, все можно было сделать гораздо проще".
Подскажите, пожалуйста, что можно упростить в приведенном выше коде?
Спасибо.
Ответ:

Не по теме:

в Perl6, который выходит в декабре,
первые несколько членов ряда и количество ты указываешь сам,
а о шаге и типе прогрессии догадывается сам компилятор.

Вывести первые 10 членов ряда:

Perl 6
1
say (1,3 ... *)[^10]        #  догадка об арифмет.прогр
Кликните здесь для просмотра всего текста
1 3 5 7 9 11 13 15 17 19

Perl 6
1
say (1,3,9 ... *)[^10]      # догадка о геометр. прогрессии
Кликните здесь для просмотра всего текста
1 3 9 27 81 243 729 2187 6561 19683


но можно дяде-компилятору и подсказать:
Perl 6
1
say ( 1, 1, *+* ... * )[^20]      # *+* - это тело анонимной функции(замыкание)
получился ряд Фибоначчи
Кликните здесь для просмотра всего текста
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765

Вопрос: Скрипт запускается, но ничего не делает

Доброго времени суток. Скрипт должен рекурсивно просматривать папки и менять расширение на первую букву у файлов, размер которых меньше заданного во втором аргументе. Первый аргумент - директория. Еще скрипт не должен менять сам себя. Что у меня неправильно?
Код 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
#!/bin/bash
if [[ "$1" == "?" ]]
    then
            echo "скрипт меняет расширение на первую букву у тех файлов,\n размер которых меньше заданного во втором аргументе. "
        exit 1
fi
case $# in
        2) dirname=$1
          fsize=$2 ;;
        0) read -p "Введите адрес директории >>>  " dirname
          read -p "Введите размер файлов для замены суфикса >>>  " fsize ;;
        *) echo "Использование: скрипт директория размер"
          exit 1 ;;
esac
if [[ -d "$dirname" ]]
    then
            find "$dirname" -type f -size -$fsize not -samefile BASH_SOURCE  | while IFS='\n' read file
            do
                dir_name=$(dirname $file)
                file_name=$(basename $file)
                prefix=$(expr substr $file_name 1 1)
                suffix=${file_name##*.}
                newfilename=$dirname/${file_name%%$suffix}$prefix
            done
    else
            echo "Неправильное имя/адрес директории"
        exit 1
fi
Ответ: почему не роботает скрипт?
Код 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
#!/bin/bash
clear
while :
do
echo ----------------------------------------------------
echo Вітаємо вас Це Лабараторна робота № 2 яку виконав 
echo ----------------------------------------------------
echo "[1]" Якщо бажаєте вийти з прогами введіть 1
echo "[2]" Якщо бажаєте визначити кількість запущених даним користувачем процесів bash 
echo "[3]" Якщо бажаєте завершити всі процеси bash даного користувача
echo ----------------------------------------------------
echo  Зробіть ваш вибір 
echo ----------------------------------------------------
 
read nomer
 
case "$nomer" in
 
1 ) 
exit
;;
2 )
 
while read name && [ "$name" != "exit" ]
do
    if [ $name != $infousers ]
        then echo -e "Нет такого пользователя\n";
    fi
    ps -u "$name"|grep 'bash$';
;;
 
* )
echo ----------------------------------------------------
echo EROR
echo ----------------------------------------------------
echo Ви ввели не вірну команду \"$nomer\"
echo ----------------------------------------------------
echo EROR
echo ----------------------------------------------------
;;
esac
done
Вопрос: Определение расширения файла

Здравствуйте, не могу понять, как проверить расширения файла и подсчитать, вот что у меня получилось, что мб не так
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
int_counter=0
cont=again
while [ "$cont" = "again" ]
do
    echo "Enter a name of a next file: "
    read str
    if [ "$str | grep 'C source'" ]; then
        int_counter=`expr $int_counter + 1`
    fi
    echo "Enter again, if you have to continue: "
    read cont
done
echo $int_counter
В конце выводит 3, если ввел три файла
Ответ:
Bash
1
ftype[${#ftype[*]}]=$(file -b "$str" | cut -d, -f1)