Как стать автором
Обновить

Комментарии 38

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

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

Вот так всё просто.
НЛО прилетело и опубликовало эту надпись здесь
ну «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
НЛО прилетело и опубликовало эту надпись здесь
Есть такое дело, называется регулярные выражения (соб-но отличие 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
НЛО прилетело и опубликовало эту надпись здесь
also, вбейте в гугл bash for и попадаете на мою любимую хавту по циклам for в баше.
НЛО прилетело и опубликовало эту надпись здесь
grab.by/3rhH -> www.cyberciti.biz/faq/bash-for-loop/ сам ей надавно пользовался так как надо было после долго неписание скриптов написать добавление метаданных к >200 серий аниме :)
НЛО прилетело и опубликовало эту надпись здесь
а это по вашему что?
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
НЛО прилетело и опубликовало эту надпись здесь
тут все построчно для удобства чтения, переписать в одну строчку не сложно. Пишите статья про баш и не знаете, что $@ массив аргументов? похвально…
НЛО прилетело и опубликовало эту надпись здесь
извиняюсь, но все равно похвально. такие вещи как $0 $1 $$ $! $? $@ надо бы знать.
НЛО прилетело и опубликовало эту надпись здесь
в прошлой жизне я был гуру баш скриптинга. помню написал на нем свой интерактивный шелл для простенького администрирования.
p.s.
на opennet'e есть толстый учебник на русском по башу.
НЛО прилетело и опубликовало эту надпись здесь
жаль, по заголовку ожидал каких-то трюков, вкусностей, а тут все до ужаса банально. Переименуйте что ли в «обычный такой 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 на серверах и не помню чтобы такое говорил. Второе я считаю что если пишешь что то что дальше будет кем то использоваться то надо это делать так чтобы было меньше привязок к чему то узкоспециальному.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории