Pull to refresh

Comments 38

RTFM и ваши волосы будут мягкие и шелковистые… :)
UFO just landed and posted this here
O_o
man bash, man find, man grep/egrep/fgrep/rgrep
UFO just landed and posted this here
UFO just landed and posted this here
Вообще-то вопрос интересный. Это я в защиту автора, просто чтоб пояснить. Вопрос в том, что считать расширением… после последней точки, или после первой. Почему вопрос, поясню — есть же расширения типа *.tar.gz.
то есть, если мы считаем расширение после последней точки, тогда:
file=1.tar.gz
filename=${file%.*}
ext=${file##*.}

если же наоборот, мы считаем расширение после первой точки, то:
file=1.tar.gz
filename=${file%%.*}
ext=${file#*.}

Вот так всё просто.
UFO just landed and posted this here
ну «for i in» буквально означает перебирать то в чем ищите, а искать надо в списке, "*.txt" это не список файлов это просто строка. я обычно делаю как то так

#!/bin/sh
ls -la | while read tfile
do
echo "$tfile"
done

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

вот пример цикла с for

for i in `seq 1 100`; do
echo "$i"
done
UFO just landed and posted this here
Есть такое дело, называется регулярные выражения (соб-но отличие grep от egrep, к примеру), так вот, если их освоить, все становиться просто волшебно… Но они сложны.
По Вашему вопросу:
[code]
for foo in `find some_file_with_some_expressions`; do grep/xargs/some_thing_else $foo; done;
[/code]

прекрасно выполняет что хотите с каким угодно кол-вом файлов, отобранных по определенным признакам.
bash scripting >> google сразу же на учебник попадаем.

p.s.
я жу говорил, что тут дружно маны читают…

>Кстати, раз уж вы позиционируете себя как гуру баша, может расскажите как найти полное описание, как делать цикл for по файлам? Вроде, for i in *.txt; do smth i; done. Полное описание синтаксиса, как использовать результаты (например только имя файла, без расширения) и т.д. Заодно расскажете, как нашли. Вот и проверим действенность совета.

for file in *.txt
name="${file%%.*}"
ext="${file##*.}"
echo $name
echo $ext
done

жаже вот вам больше:
if ping -c 2 -q ya.ru;then if [ -e /tmp/down];then echo «inet podnyalsa»;rm /tmp/down; fi; else echo «inet upal»;touch /tmp/down; fi
UFO just landed and posted this here
also, вбейте в гугл bash for и попадаете на мою любимую хавту по циклам for в баше.
UFO just landed and posted this here
grab.by/3rhH -> www.cyberciti.biz/faq/bash-for-loop/ сам ей надавно пользовался так как надо было после долго неписание скриптов написать добавление метаданных к >200 серий аниме :)
UFO just landed and posted this here
а это по вашему что?
Following shell script will go though all files stored in /etc directory. The for loop will be abandon when /etc/resolv.conf file found.

#!/bin/bash
for file in /etc/*
do
if [ "${file}" == "/etc/resolv.conf" ]
then
countNameservers=$(grep -c nameserver /etc/resolv.conf)
echo «Total ${countNameservers} nameservers defined in ${file}»
break
fi
done

#!/bin/bash
FILES="$@"
for f in $FILES
do
# if .bak backup file exists, read next file
if [ -f ${f}.bak ]
then
echo «Skiping $f file...»
continue # read next file and skip cp command
fi
# we are hear means no backup file exists, just use cp command to copy file
/bin/cp $f $f.bak
done
UFO just landed and posted this here
тут все построчно для удобства чтения, переписать в одну строчку не сложно. Пишите статья про баш и не знаете, что $@ массив аргументов? похвально…
UFO just landed and posted this here
извиняюсь, но все равно похвально. такие вещи как $0 $1 $$ $! $? $@ надо бы знать.
UFO just landed and posted this here
в прошлой жизне я был гуру баш скриптинга. помню написал на нем свой интерактивный шелл для простенького администрирования.
p.s.
на opennet'e есть толстый учебник на русском по башу.
UFO just landed and posted this here
жаль, по заголовку ожидал каких-то трюков, вкусностей, а тут все до ужаса банально. Переименуйте что ли в «обычный такой bash».
Смущает что начали с bash, и не закончив про него, сразу прыгнули на отдельные комманды, grep и find.
Начинающим будет полезно. Но всё-таки попробуйте быть последовательным, не перескакивая.
За статью спасибо!
Всё настолько плотно друг с другом связывается, что я без лишнего угрызения совести поставил утилиты GNU под флаг Bash, что концептуально неправильно, но доступно для понимая новичками. И верно, я подчёркиваю, что статья для начинающих. Для них (а я сам таким был) это нетривиально. Я видел как ограниченно многие Линуксоиды используют консоль — ssh и для ребута сервисов, разве что. А на Хабре есть люди разного уровня подготовки. Кому-то да пригодится.

Спасибо за замечание, постараюсь быть более последовательным. Хочется о многом рассказать, а раздувать статью наоборот, не хочется.
Не увидел нетривиального bash-а, хотя статья вроде называется «Нетривиальный BASH.» но про баш почему то ни слова…
Я чуть выше уже объяснился почему «нетривиальный». Для вас «банальный», и это хорошо. Всё ведь зависит от уровня подготовленности читателя, согласны?

Примечание для себя: впредь быть осторожнее с заголовками, они вводят в заблуждение.
Так может быть, стоит поправить заголовок? Сам в баше не очень разбираюсь, но после прочтения всё равно возникает вопрос: а что же тогда тривиально, если не это? echo «Hello, World!» что ли?
Количество озадаченных комментаторов ясно указало мне на желтуху заголовка. Сменил на другой. Надеюсь так лучше и никого не смущает.
alias isff='if ps aux | grep firefox | grep -v grep > /dev/null; then echo «Firefox запущен»; fi'

тут не хватает грепа имени пользователя. Обычно это нужно (т.к. мне может быть пофег, что фаерфокс запущен у какого-то др пользователя):
grep `id -un`
if ps aux | grep firefox | grep -v grep
Откройте для себя pgrep

И вот не в обиду, но вы немножко не за тот шелл взялись. Честно.
Я вам как бы намекну, что на данный момент действительно пронизано и рекомендуется:
Сравните и скажите, что проще:
bash:
1. find. '*.c' -print | xargs grep 'hello' /dev/null
2. for i in `ls *.tar.bz2`; do tar xjf "$i"; done

zsh:
1. grep hello $(ls **/*.c)
2. for i in *.tar.bz2;tar xjf "$i"
Холиварно :) Незаменимых вещей нет и Bash легко меняется на тот же zsh. Всё равно не может существовать единственно универсального решения, но я хотел бы, что бы в Линуксе, с которым я плотно работаю, хоть что-то было постоянным от дистрибутива к дистрибутиву. Пусть это будет GNU и пусть это будет Bash.
>
>Сравните и скажите, что проще:
>bash:
>1. find. '*.c' -print | xargs grep 'hello' /dev/null
>2. for i in `ls *.tar.bz2`; do tar xjf "$i"; done
>
>zsh:
>1. grep hello $(ls **/*.c)
>2. for i in *.tar.bz2;tar xjf "$i"

ненене дэвид блэйн, одно дело пользоваться zsh для своего удобства, второе писать скрипты для общих случаев, в скриптах не место не bash-измам не zsh-измам, мое сугубое имхо.
Вы серьёзно думаете что
if ps aux | grep firefox | grep -v grep
используется в некоей гетерогенной среде где требуется универсальность и совместимость?
У вас на серверах тоже крутится firefox?
я не понимаю вашего вопроса, я не использую firefox на серверах и не помню чтобы такое говорил. Второе я считаю что если пишешь что то что дальше будет кем то использоваться то надо это делать так чтобы было меньше привязок к чему то узкоспециальному.
Sign up to leave a comment.

Articles