1 (18.11.2011 19:26:37 отредактировано Student_novi4ok)

Писать не прошу, т.к. хочется самому, но только столкнулся с такой проблемой, не совсем понимаю задание. И вот еще какой вопрос, как я понял по первому пункту, что пользователь вводит имя каталога, не путь а именно имя, и чтобы в нем искать файлы, то в него надо перейти, как "перепрыгнуть" через, допустим, 2 каталога и попасть в третий???? Заранее спасибо, сам пока новичок в этом деле, преподаватель говорит ищите ответы на вопросы сами. поэтому и обращаюсь сюда, чтобы хоть кто-то подсказал!

Написать shell-процедуру, которая:
-находит в заданном каталоге все файлы, имена которых вводятся при работе процедуры по запросу
выводимому на экран;
-в каждом найденном файле ищет строку, не содержащую слово, переданное первым параметром;
-если такая строка имеется в файле, то на экран выводится её номер(или номера, если таких строк несколько);
при отсутствии в файле таких строк выводит соответствующее сообщение.

набрасал немного кода, как я понял надо чтобы запросы имен файлов записывались в массив, потому что искать сроку сразу не совсем рационально будет=)
проверьте и подскажите как быть дальше, т.к. это максимум до чего додумался

#!/bin/bash
echo

#------------------------#
#Переход в нужный каталог#
#------------------------#
echo "Введите имя каталога, для получения полного пути и перехода к нему"; read a;
find -type d -name $a;
echo
echo "Выберите нужный вам каталог из списка выше";
echo "Перейдите в каталог, указав путь, который указан выше, используя команду cd";
read b;
echo
#--------------------------#
#Ввод файлов для нахождения#
#--------------------------#
while true
do
echo "Введите имя файла для поиска ";
read c;
d=$(find $b  -type f -name "$c");
echo
ls -l $d | awk '{ print $8 "         размер: " $5 }'
#if [ ! -e $d" ]
#then 
#      echo Файл $c не найден! ";echo
#fi
# d=find $b -type f -name $c'
# ARRAY=( $d )
echo "Хотите закончить ввод ?    Y/N";
read q;
case $q in
"Y") break ;;
*) ;;
esac
done

3

Student_novi4ok пишет:

-находит в заданном каталоге все файлы, имена которых вводятся при работе процедуры по запросу

"в заданном каталоге" - задаётся именно путь(можно схитрить и сказать, что ищем в текущем). но это лучше уточнять у того, кто дал вам задание... имена файлов вводятся интерактивно. для чтения используется read, для поиска - find. результат find'а сохраняем в переменной. или можно сразу пустить его на вход функции - второй части.
Во второй часть grep'аем эти файлы и разрезаем вывод cut'ом.

по поводу кода: отформатируйте его и задайте осмысленные имена переменным. Без этого никто в нём разбираться не захочет...

95% процентов проблем находятся между клавиатурой и стулом.
Fat-Zer пишет:

результат find'а сохраняем в переменной. или можно сразу пустить его на вход функции - второй части.

На счет чтобы заносить в переменную, я понял, но не совсем понял как именно это делается, не могли бы показать наглядно, так быстрее пойму

#!/bin/bash
echo

#------------------------#
#Переход в нужный каталог#
#------------------------#
echo "Введите имя каталога, для получения полного пути и перехода к нему"; 
read namecat;
f=$(find -type d -name "$namecat")  #поиск каталога по введенному имени, результат заносится в переменную f
echo

#--------------------------#
#Ввод файлов для нахождения#
#--------------------------#
while true    #цикл ввода файлов, пока пользователь не введет Y
do
    echo "Введите имя файла для поиска ";
    read namefile;
    d=$(find $f  -type f -name "$namefile");   #d-переменная, в которую заносится найденный файл
    echo
    if [ ! -e "$d" ]   #если файл не найден, то выводится соответствующее сообщение
    then 
        echo "Файл $namefile не найден! ";\
    else
        ls -l $d | awk '{ print $8 "         размер: " $5 }';    #вывод информации о файле: имя и размер
    fi
    echo "Хотите закончить ввод ?    Yes/No";
    read q;   #Ввод символа для продолжения ввода или завершения
    case $q in
        "Y") break ;;
        "y") break ;;
        "yes") break ;;
        *) ;;
    esac;
done

Так правильнее, осталось только понять как заносить в переменную, но я так понял что наверное лучше в массив. можете наглядно примерами показать как лучше???

Изобретение новых тегов приветствуется, но пока не работает.
Отформатировано.

6

Student_novi4ok пишет:

осталось только понять как заносить в переменную, но я так понял что наверное лучше в массив.

да в общем с этим всё правильно. Массивы в баше - тема отдельного разговора.... да и применяются они крайне редко.
неправильно то, как потом с этим списком работаете... надо что-то в роде этого:

for FILE in $d; do
    echo "===== $FILE ====="
    grep "строка" "$FILE"
done

ну и в цикле что-там-надо...

пара замечаний по стилю(больше личных):
- глобальные переменные удобно набирать капсом - так они явно выделяются...
- почти всё, что содержит $ лучше заключать в двойные кавычки, если не требуется обратное.
- then и do можно писать на той же строке, что и условия/циклы через ';' - экономит место,да и просто ИМХО приятней...

95% процентов проблем находятся между клавиатурой и стулом.

Спасибо за замечания, учту) просто это так сказать первый мой скрипт) вопрос еще один назрел, как думаете это так оставить или лучше переделать с функциями?

а тот цикл который вы написал for, его надо прям после поиска файла вставлять? как я понял по заданию, то это должно выполняться после введения всех файлов, разве нет?

9

Student_novi4ok пишет:

как думаете это так оставить или лучше переделать с функциями?

не стоит...  тут особо ничего не выделишь...

Student_novi4ok пишет:

а тот цикл который вы написал for, его надо прям после поиска файла вставлять? как я понял по заданию, то это должно выполняться после введения всех файлов, разве нет?

как "должно быть" лучше спрашивать у того, кто выдал задание. вставляйте, куда нужно.... можно в else условия. кстати следует проверять на "-z", иначе будет белиберда, если файлов несколько...

95% процентов проблем находятся между клавиатурой и стулом.
#!/bin/bash
echo
#------------------------#
#Переход в нужный каталог#
#------------------------#
echo "Введите имя каталога, для получения полного пути и перехода к нему"; 
echo
read NAMECAT;
F=$(find -type d -name "$NAMECAT")  #поиск каталога по введенному имени, результат заносится в переменную f
echo
#--------------------------#
#Ввод файлов для нахождения#
#--------------------------#
while true    #цикл ввода файлов, пока пользователь не введет Y
do
echo "Введите имя файла для поиска ";
read NAMEFILE;
D=$(find $F  -type f -name "$NAMEFILE");   #d-переменная, в которую заносится найденный файл
#echo
#if [ ! -e $D" ]   #если файл не найден, то выводится соответствующее сообщение
#then 
#      echo Файл $namefile не найден! ";\
#else
#ls -l $D | awk BEGIN { print    Name file     Size of file\n-----------------------------}  {print $8       " $5}';    #вывод информации о файле: имя$
#fi
echo "Хотите закончить ввод ?    Y/N";
read Q;
case $Q in
"Y") break ;;
"y") break ;;
"yes") break ;;
*) ;;
esac;
done;
echo
echo "Введите слово для поиска в строках "
read STR;
for FILE in $D
do
echo "===== $FILE ====="
grep -n -v "$STR" $FILE;
done

Так?? Только если как у меня делать поиска слова, то он ищет только в последнем введенном файле. ЗЫ. Вводил два имени файла, он вывел строки только второго файла. первый даже не рассматривался.

Расставьте отступы. Я это делать больше не буду. Fat-Zer

11

http://linuxforum.ru/viewtopic.php?pid=201762#p201762 - по первой части задания , может сгодится , только подправить надо

" si contuderis stultum in pila quasi tisanas feriente desuper pilo non auferetur ab eo stultitia eius " © Proverbs 27:22
gramozeka пишет:

http://linuxforum.ru/viewtopic.php?pid=201762#p201762 - по первой части задания , может сгодится , только подправить надо

Спасибо, но вроде то что есть вроде работает нормально, сомневаюсь только на счет поиска каталога, который введен

gramozeka пишет:

http://linuxforum.ru/viewtopic.php?pid=201762#p201762 - по первой части задания , может сгодится , только подправить надо

while [ "$a" -lt "${#packagesA[*]}"  ]
do
if  ls /var/log/packages/ | grep ${packagesA[$a]} &> p
then echo "найден " "$p"
else echo "${packagesA[$a]}" "не найден"
fi
a=$(($a+1))
done

если правильно понял то тут осуществляется поиск?

14

Student_novi4ok пишет:

если правильно понял то тут осуществляется поиск?

да , в этой строчке :

if  ls /var/log/packages/ | grep ${packagesA[$a]} &> p

здесь :

ls /var/log/packages/

можно разместить свою конструкцию ...

тыц - читай мануал по башу , там всё доходчиво .. wink

" si contuderis stultum in pila quasi tisanas feriente desuper pilo non auferetur ab eo stultitia eius " © Proverbs 27:22
gramozeka пишет:

тыц - читай мануал по башу , там всё доходчиво .. wink

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

Fat-Zer пишет:

можно в else условия. кстати следует проверять на "-z", иначе будет белиберда, если файлов несколько...

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

#!/bin/bash
echo
#------------------------#
#Переход в нужный каталог#
#------------------------#
echo "Введите имя каталога, для получения полного пути и перехода к нему"; 
echo
read NAMECAT;
F=$(find -type d -name "$NAMECAT")  #поиск каталога по введенному имени, результат заносится в переменную f
echo
echo "Введите слово для поиска в строках "
echo
read STR;
echo
#--------------------------#
#Ввод файлов для нахождения#
#--------------------------#
while true    #цикл ввода файлов, пока пользователь не введет Y
do
echo "Введите имя файла для поиска ";
echo
read NAMEFILE;
D=$(find $F  -type f -name "$NAMEFILE");   #d-переменная, в которую заносится найденный файл
echo
if [ ! -e "$D" ]  #если файл не найден, то выводится соответствующее сообщение
then 
echo "Файл $namefile не найден!";echo;continue;\
else
ls -l $D | awk 'BEGIN { print"    Name file     Size of file\n-----------------------------"}  {print $8 "      " $5}';    #вывод информации о файле: $
fi
echo
echo "===== $D ====="
echo
echo "Строка(и) не содержащие слово $STR:"
echo
grep -n -v "$STR" $D || echo "    Нет строк    "
echo
echo "Хотите поменять слово для поиска ?   Yes/No";
read x;
echo
case $x in
"y"*) echo "Введите слово для поиска";echo; read STR ;;
"Y"*) echo "Введите слово для поиска";echo; read STR ;;
*) ;;
esac;
if  [ "$x" = "n" -o "$x" = "N" -o "$x" = "No" -o "$x" = "nO" ]
then
echo 
echo "Хотите закончить ввод ?    Y/N";
echo 
read Q;
case $Q in
"Y"*) break ;;
"y"*) break ;;
*) ;;
esac;
fi
done;

Вот что получилось, все работает.

Можете помочь, сделать так, чтобы вводимые имена файлов записывались в массив. очень надо. буду очень благодарен! заранее спасибо!

#!/bin/bash
echo
#------------------------#
#Переход в нужный каталог#
#------------------------#
echo "Enter the name of the directory:"; 
echo
read NAMECAT;
F=$(find -type d -name "$NAMECAT")  #поиск каталога по введенному имени, результат заносится в переменную f
echo
echo "Enter a search word:"
echo
read STR;
echo
echo "Enter the number of files for input"
read q;
#--------------------------#
#Ввод файлов для нахождения#
#--------------------------#
while true    #цикл ввода файлов, пока пользователь не введет Y
do
for i in q; do
echo "Enter the file name:";
echo
read NAMEFILE;
D=`find $F  -type f -name "$NAMEFILE"`;   #d-переменная, в которую заносится найденный файл
echo
if [ ! -e "$D" ]  #если файл не найден, то выводится соответствующее сообщение
then
echo "File $namefile not found!";echo;continue
fi;
ARR=$( "${ARR[*]}" "$NAMEFILE" );\
done
for index in q
do
echo "======= ${ARR[index]} ======="
echo
ls -l $D | awk 'BEGIN { print"    Name file     Size of file\n-----------------------------"}  {print $8 "      " $5}';\
echo
echo "The string don't contain the word $STR:"
echo 
grep -n -v "$STR" "${A[index]}" || echo "   Нет строк    "
done;
echo "Do you want to finish ?    Y/N";
echo
read Q;
case $Q in
"Y"*) break; echo ;;
"y"*) break;echo  ;;
*) ;;
esac;
done;

Подкорректируйте пожалуйста массив

20

Student_novi4ok пишет:

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

примерно так:

while read FILE; do
    FILES+=" $FILE"
done
Student_novi4ok пишет:

после какого else надо делать -z, чето не пойму, с параметрами вообще не дружу.

учитывая, что там только один if, то выбор не большой... man test расскажет, в чём отличие.

Student_novi4ok пишет:

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

гмм... у меня сложилось впечатления, что вы просили помочь разобраться, а не писать всё за вас... =/

Student_novi4ok пишет:

Подкорректируйте пожалуйста массив

уже не раз намекал на то, что нужно расставить отступы. без этого копаться в этом нет никакого желания...

95% процентов проблем находятся между клавиатурой и стулом.

Согласен, писать за меня не просил и по сути не прошу писать все, прошу только помочь в том, чего сам никак не пойму. Если расставлю отступы, сможете помочь?

22

Student_novi4ok пишет:

Если расставлю отступы, сможете помочь?

.. а я бы ещё гранату бросил , .. для пущей надёжности  :lol: , ...

" si contuderis stultum in pila quasi tisanas feriente desuper pilo non auferetur ab eo stultitia eius " © Proverbs 27:22

если это поможет, готов кинуть =)

24 (20.11.2011 13:53:04 отредактировано zenon)

gramozeka, вот так вот слова доводят до гранатометания.  :lol:, ты это,... осторожней.

История показывает, что во всем новом обычно кроется какой-то подвох.
Классическая ошибка, которую совершают проектировщики
абсолютно надежных систем, - недооценка изобретательности клинических идиотов.
newzenon пишет:

gramozeka, вот так вот слова доводят до гранатометания.  :lol:, ты это,... осторожней.

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

26

Student_novi4ok, тут вот что есть - перевод на русский - http://linuxforum.ru/viewtopic.php?id=181
http://www.bash-scripting.ru/abs/chunks/index.html

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

История показывает, что во всем новом обычно кроется какой-то подвох.
Классическая ошибка, которую совершают проектировщики
абсолютно надежных систем, - недооценка изобретательности клинических идиотов.
#!/bin/bash
echo
#------------------------------------#
#Переход в нужный каталог#
#-----------------------------------#
 echo "Enter the name of the directory:"; 
 echo
 read NAMECAT;
    F=$(find -type d -name "$NAMECAT")  #поиск каталога по введенному имени, результат заносится в переменную f
 echo
 еcho "Enter a search word:"
 echo
 read STR;
 echo
 echo "Enter the number of files for input"
 read q;
#---------------------------------------#
#Ввод файлов для нахождения#
#---------------------------------------#
    while true; do    #цикл ввода файлов, пока пользователь не введет Y
        for i in q; do
           echo "Enter the file name:";
           echo
           read NAMEFILE;
           D=`find "$F"  -type f -name "$NAMEFILE"`;   #d-переменная, в которую заносится найденный файл
           echo
             if [ ! -e "$D" ]  #если файл не найден, то выводится соответствующее сообщение
             then
                   echo "File $namefile not found!";echo;continue
             fi;
        ARR=$( "${ARR[*]}" "$NAMEFILE" );\
    done
    for index in q; do
       echo "======= ${ARR[index]} ======="
       echo
       ls -l $D | awk 'BEGIN { print"    Name file     Size of file\n-----------------------------"}  {print $8 "      " $5}';\
       echo
       echo "The string don't contain the word $STR:"
       echo 
       grep -n -v "$STR" "${A[index]}" || echo "   Нет строк    "
    done;
    echo "Do you want to finish ?    Y/N";
    echo
    read Q;
    case $Q in
        "Y"*) break; echo ;;
        "y"*) break;echo  ;;
             *) ;;
    esac;  

Так лучше?

а как там присоединиться

Стоп, я кажется понял суть этого проекта, но к сожалению переводить я не умею, да и если уж на то пошло, как говорится зачем изобретать велосипед, когда есть машина?!, я уже говорил выше, так вот повторюсь, что решил быть программистом PHP/HTML-верстальщик, что по сути с башем ничего общего не имеет, но в отличие от других, я не прошу все мне написать я все сам написал ищя в мануал что и как пишется, но в массивах никак не пойму ничего, и прошу хотя бы объяснить

gramozeka, вы можете просто проверить мой код выше там уже с массивами, только пишет ошибку:
42: Bad substitution
42: Bad substitution
не пойму что это значит