Пишу скрипт и я не могу сообразить как поменять третье (150000) слово на "1" в строке:#l# 1284725281 150000
учитывая, что третье слово может быть разной длиной, а второе всегда одинаковой, но с разными цифрами
Я примерно вот так начал писать, а дальше не соображу:
sed 's/^#l#\ [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\ /#l#\ "вот тут уже не соображу"' ahistory.dat
echo "#l# 1284725281 150000" | awk '{print $1,$2,$3=1}'
> Пишу скрипт и я не могу сообразить как поменять третье (150000) слово
> на "1" в строке:
> #l# 1284725281 150000
> учитывая, что третье слово может быть разной длиной, а второе всегда одинаковой,
> но с разными цифрами
> Я примерно вот так начал писать, а дальше не соображу:
> sed 's/^#l#\ [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\ /#l#\ "вот тут уже
> не соображу"' ahistory.dat
>awk '{print $1,$2,$3=1}'{$3=1;print}
{$NF=1;print}
Bash только:
shopt -s extglob
str="#l# 1284725281 150000"
echo "${str/% *([[:digit:]])/ 1}"
echo "или если слово с буквами и цифрами"
echo "${str/% *([[:alnum:]])/ 1}"Sed:
str="#l# 1284725281 150000"
sed 's/ [0-9]*$/ 1/' <<< "${str}"В обоих случаях использованы регулярные выражения, они ресурсоёмкие. А использование pipe "|" влечёт за собой +1 вызов экземпляра shell. На это, в свою очередь, тоже расходуются ресурсы-время. Какой из трёх вариантов (bash только, awk, sed) и в какой ситуации быстрее - не знаю.
Кстати, вопрос ко всем, что быстрее работает (или должно бы быть быстрее)?
P.S. Без регулярных выражений, Bash,
условившись о постоянной длине первых двух слов:
str="#l# 1284725281 150000"
str="${str:0:14} 1"
echo "${str}"
str="$(cut -c1-14 <<< "${str}") 1"
echo "${str}"
Забыл. :) Если без длины слов, но условие - меняем последнее в строке слово:
str="#l# 1284725281 150000"
str="${str% *} 1"
echo "${str}"
Af,
Что бы узнать, что быстрее работает - выполните time:
#time [command or script]
Насколько мне хватает компетенции, я могу сказать, что в "погоне за временем" стараются придерживаться нескольких правил:
1. Если все можно сделать на sed, то это будет быстрее чем sed + awk или + cut или + grep. Правило действует на все утилиты.
2. Меньше пайпов, это следует,в принципе, из правила 1.
3. sed работает быстрее всех. (это я где-то прочитал, проверял пару раз - поддтвердилось)А что касается реализации решения задачи на bash, то прошу расписать как ваша конструкция работает, ибо я 1й раз такое вижу.
пс: а как вам мое решение?
> Забыл. :) Если без длины слов, но условие - меняем последнее в
> строке слово:
>
> str="#l# 1284725281 150000"
> str="${str% *} 1"
> echo "${str}"
>
>> str="${str% *} 1"
>>
> как ваша конструкция работает, ибо я 1й раз такое вижу.
> пс: а как вам мое решение?Оно работает, что главное. С точки зрения простых манипуляций логами - не вижу принципиальных отличий между sed и awk. Склонен согласиться с http://stackoverflow.com/a/367014 Не могу оценивать с точки зрения сложных "рефаторингов" какого либо текста или кода. Но, не обладая доскональным пониманием синтаксисов как awk/sed, так и текста-цели, страшновато для сложных вещей "изобретать" собственные реализации инструментов на базе sed/awk и т.п. Неприятны вероятность ошибки и траты на исправления.
Конструкция ${parameter%pattern} описана в разделе Parameter Expansion из man bash. '%' - оператор отрезать суффикс от значения переменной. То что правее '%' - шаблон, что подходит под шаблон вырезается. Если % одиночный, цель наикратчайшее совпадение. Двойной - самое длинное. '% *' означает последний пробел и что правее него.
>>> str="${str% *} 1"
>>>
>> как ваша конструкция работает, ибо я 1й раз такое вижу.
>> пс: а как вам мое решение?
> Оно работает, что главное. С точки зрения простых манипуляций логами - не
> вижу принципиальных отличий между sed и awk.здесь Вы не правы:
основное преимущество sed, в том, что он ПОСТРОЧНО обрабатывает вход => минимальное потребление ресурсов ОС и независимость от размера входящего потока данных.
основное преимущество awk в том, что его гибкость (читай использование скриптов) позволяет выполнить практически любую операцию над входным потоком данных и включать его в КОНВЕЙЕР. Он в отличие от sed работает не построчно с входящими данными, а с их блоками, что позволяет организовать более тонкую обработку. Но ресурсов ОС жрет тоже не много
sed и awk - это классика.
>[оверквотинг удален]
> Не могу оценивать с точки зрения сложных "рефаторингов" какого либо текста
> или кода. Но, не обладая доскональным пониманием синтаксисов как awk/sed, так
> и текста-цели, страшновато для сложных вещей "изобретать" собственные реализации инструментов
> на базе sed/awk и т.п. Неприятны вероятность ошибки и траты на
> исправления.
> Конструкция ${parameter%pattern} описана в разделе Parameter Expansion из man bash. '%'
> - оператор отрезать суффикс от значения переменной. То что правее '%'
> - шаблон, что подходит под шаблон вырезается. Если % одиночный, цель
> наикратчайшее совпадение. Двойной - самое длинное. '% *' означает последний пробел
> и что правее него.А тут я с Вами соглашусь. Поскольку задача явно скорее студенческого характера, то большие объемы данных обрабатывать вряд ли придется (sed/awk не нужен). Так что лучше пользоваться нативными средствами шела.