Awk - рецепты

Материал из rrv-wiki
Перейти к навигации Перейти к поиску

Содержание

Массовое переименование файлов

Конечно не avk но очень удобно. Использовать когда надо удалить какие то символы у имен файлов в папке. Например тут заменяем "+" на "_"

rename 's/\+/_/g' * 

grep полезные ключи

-i игнорировать регистр
-A4 выводить еще 4 строки следующие за найденной
-v выводить все кроме найденных
поиск в файлах в директории:

egrep то_что_ищем ./*

sed убираем жадность регулярного выражения

Дело в том, что регулярные выражения "жадные" то есть пытаются взять максимально возможную строку которая подходит под регулярное выражение.

Например:

блабла-блабла-бла-бла

Регулярка:

echo 'блабла-блабла-бла-бла' | sed 's|||g' по моей задумке должна была убирать ,, уберет всю строку

Правильная регулярка:

$echo 'блабла-блабла-бла-бла' | sed 's|<td [^<]*>||g' блабла-блабла-бла-бла Тут регулярное выражение сокращает "жадность" до ближайшего появления символа в структуре [^символ]* в этом примере это символ "<"

Полезная ссылка

http://ltwood.wikidot.com/scripting:awk

Внешние переменные

Для того что бы передать внешнюю переменную можно воспользоваться конструкцией -v t=$temp то есть с помощью ключа -v мы передали внешнюю переменную (переменную shell) '$temp', например:

temp="Значение"
cat test.txt | /usr/bin/awk -v t=$temp 'BEGIN {FS="."} {if($5>0) print t" "$4"="$5}'

Решение ошибок типа /usr/bin/egrep: Argument list too long

Поиск (удаление, копирование и др)в длинных списках решается с помощью xargs.
Простой запрос:

egrep -i строкапоиска ./*
/usr/bin/egrep: Argument list too long

Запрос решающий проблему длинного списка:

find ./ -type f | xargs egrep -i строкапоиска

Сжатие в архив всех папок в директории

Необходимо сжать все папки в директории /home/backup_all/ по одной, а затем удалить оригиналы

home_dir="/home/backup_all/"
cd home_dir; $ls -la  grep ^d | awk '{print $9}' | grep -v ^"\." | awk -v t=$home_dir '{system ("tar cfz "$1".tar.gz "t$1" && rm -r "t$1)}'

Печать (print)

Можно задать поведение команды print используя переменные:

OFMT	- формат вывода чисел - по умолчанию:	%.6g
OFS	- разделитель полей (разделенных запятой например print $1,$2,"rrr";) - по умолчанию:	пробел
ORS	- разделитель записей (строк) - по умолчанию:	перевод строки

Печать одинарной кавычки

Так как в однострочкой команде awk мы экранируем одинарными кавычками, пример:

| awk '{print $1" "$2}'

для меня было проблемой вставить в вывод одинарную кавычку, но оказалось все просто, можно прерывать awk команду и вставлять куски обрабатываемые sh, пример:

| awk '{print $1'\'' '\''$2}'

В прерываемый элемент можно даже вставить переменную sh например ${VAR}

| awk '{print $1" "'${VAR}'}'

if

Поиск строчек с определенным регулярным выражением:

#поиск строк содержащий " - " (пробел тире пробел)
echo "НАТАЛЬЯ СЕНЧУКОВА - СЛУЖЕБНЫЙ РОМАН" | awk '{if ($0 ~ /.+ - .+/) {print $0}}'

Пример поиска точного слова в определенном столбце и работу с числами:

#Поиск Фамилии (слова Иванов именно в первом столбце) и возраста старше 30 лет ( четвертый столбец) 
echo "Иванов Иван Иванович 45 лет" | awk '{if (($1=="Иванов")&&($4>30)) print $0}'

Циклы Shell-а

Немного не по теме, но часто требуется.

min_num=1
max_num=10
i=$min_num
while [ $i -le $max_num ]; do
 echo "$i"
 i=`expr $i + 1` # в зависимости от shell также подходит i=$(($i + 1)) или i=$[i+1]
done

Перебор значений от 0000 до 9999 с помощью printf

#!/bin/sh
imax=9999
i=0
while [ $i -le $im ]; do
echo $i
printf %04d $i
i=`expr $i + 1`
done

Получение случайных чисел jot

можно использовать jot, например получение 5 случайных чисел от 1 до 100:

$ jot -r 5 1 100
84
69
43
12
25

Вот еще один пример, получить одно случайное число о 30 до 60 и выдержать паузу на это кол-во секунд:

$ sleep `jot -r 1 30 60`

Итоги

Подсчет объема всех mp3 файлов в текущей директории и во всех вложенных в нее папках:

find ./ | grep -i "\.mp3"$ | awk '{system ("ls -la \""$0"\"")}' | awk 'BEGIN{k=0} {k=k+$5} END{print k}'

Подсчет кол-ва несжатых wav файлов в текущей директории и во всех вложенных в нее папках:

find ./ | grep -i .wav$ | awk '{system ("file \""$0"\"")}' | grep PCM | awk 'BEGIN{k=0}{k=k+1}END{print k}'

Вывод партиций заполненных более чем на 90%

df -h | awk '{if (/^\/./) print $1" "$6" "$5}' | awk 'BEGIN {FS="%"} {print $1}' \
| awk '{if ($3>90) print "WARNING "$1" "$2" "$3"%"}'

Время

Ключи для дней недели:

date --date $DD +%A # DOW complete пример: воскресенье
date --date $DD +%a # DOW abreviated пример: вс
date --date $DD +%u # DOW (1..7) 1 is monday пример: 7
date --date $DD +%w # DOW (0..6) 0 is sunday пример: 0

Время минус сколько то дней минут и др

Используем ключ -v. Например время минус 1 день и вывод в виде годмесяцдень

date -v-1d +%Y%m%d

Старый вариант

Текущее время минус 1 час

date +%s | awk '{k=$1-3600; system ("date -r "k)}'

для bash в место -r используем ключ -d, а так как время в секундах то перед ним ставим @

date +%s | awk '{k=$1-3600; system ("date -d@"k)}'

Начало предыдущего часа в формате вида 21-09-2007_11-00 (день-месяц-год_час_минута)

date +%s | awk '{k=$1-3600; system ("date -r "k" +%d-%m-%Y_%H-00")}'

Может быть и по другому:

date +%s | awk '{k=$1-3600; system ("date --date=\"@"k"\" +%Y-%m-%d_%H-00")}'

Mysql

Оптимизация всех таблиц mysql

#!/bin/sh
p="MYSQL_PASSWORD"
echo "show databases;" | mysql -u root --password="$p" | grep -v "^Database" | awk '{print ("use "$0" ; show tables;")}' \
| mysql -u root --password="$p" \
| awk 'BEGIN {FS="_"}{if ($1 == "Tables") {if ($2 =="in" ) {printf "USE \`"$3; for (i = 4; i < 10; i++) {if ($i != "") printf ("_"$i)}; print ("\`;")} else {print ("OPTIMIZE TABLE \`"$0"\`;")}} else {print ("OPTIMIZE TABLE \`"$0"\`;")}}' \
|mysql -u root --password="$p" > result_optimize.txt

Ремонт всех баз данных mysql кроме некоторых

#!/bin/sh
#Скрипт ремонтирует все базы mysql кроме HTTPD_LOGS и выводит только ошибки восстановления
p="пароль_mysql"
echo "show databases;" | mysql -u root --password="$p" | grep -v "^Database" | grep -v "HTTPD_LOGS" \
| awk -v p="$p" '{system ("mysqlcheck -u root --password=\""p"\" -e --auto-repair --databases "$0)}' | grep -v "OK"

Удаление повторяющихся строк

Не awk но бывает полезно, емли нужно вывод из потока отсортировать и убрать все повторяющиеся строки:

cat file.txt | sort | uniq

Подсчет повторяющихся строк

cat file.txt | sort | uniq -с

Преобразование wav файлов в mp3

# Скрипт создает структуру каталогов в другом месте
# затем ищет все wav файлы в указанной директории, определяет что они не сжатые
# сжимает их, причем имя становится name.wav.mp3, то есть к имени файла добовляется .mp3,
# а оригиналы копирует в подготовленное дерево дирикторий

#Переходим в каталог
cd "/home/samba/archives/Архив\ рекламы\ 2004/"
#создаем структуру каталогов в /home/samba1/Архив рекламы 2004/
find ./ -type d | awk '{system ("mkdir -p \"/home/samba1/Архив рекламы 2004/"$0"\"")}'
#ищем все wav файлы, сжимает их, а оригиналы копирует в подготовленное дерево дирикторий
find ./ | grep -i .wav$ \
| awk '{system ("file \""$0"\""); print $0}' \
| awk '/PCM/ {getline; system ("/usr/local/bin/lame -m s -b 256 \""$0"\" \""$0".mp3\" && mv \""$0"\" \"/home/samba1/Архив рекламы 2004/"$0"\"")}'

Смена биртрейта mp3 файла

Уменьшим битрейт до 8 бит моно mp3 файлов в одной папке в три потока

#!/bin/sh

I=/home/rrv/mp3/
O=/home/rrrv/mp3_8bit/

mkdir ${O}
cd ${I}
ls | awk -v outdir=${O} '{printf ("lame -m m -b 8 \""$0"\" \""outdir$0"\" & "); getline; printf ("lame -m m -b 8 \""$0"\" \""outdir$0"\" & "); getline; print ("lame -m m -b 8 \""$0"\" \""outdir$0"\"");}' | awk '{system ($0);}'

Склеивание нескольких mp3 в один

ls *.mp3\
| awk 'BEGIN{i=0;}{k[i]=$0;i++}END{printf "ffmpeg -i \"concat:"; for (j in k){printf k[j]"|"}; print "\" -acodec copy output.mp3"}' \
| awk '{system ($0)}'

Хотя есть второй вариант, пусть меломаны проверят:

cat *.mp3 > output.mp3

Поиск пакетов с удаленными файлами

Один раз случайно удалил папку /usr/X11R6 во время установки пакета gd. Помогла вот такая уродливая последовательность команд:

pkg_info | awk '{system("pkg_info -L "$1)}' | awk '/X11R6|Information/ {print $0}' \
| tr "\n" " " | awk 'BEGIN {FS = "Information\ for "} { for (i = 1; i < NF+1; i++) print $i }' \
| grep /X11R6 \
| awk 'BEGIN {FS = ": | "} { system ("echo "$1" >> /tmp/rm.list"); for (j = 2; j < NF+1; j++) system ("ls "$j" 2>> /tmp/rm.list ") }' \
> /dev/null

В файле /tmp/rm.list можно было обнаружить по сообщениям ошибок какие порты необходимо пересобрать.

Поиск директорий размер которых привышает 3Gb

Глубина поиска 7 по директории /home. Будут отображены папки больше 3Gb

du -h -d 7 /home \
| awk ' /^ *[0-9]+(,[0-9]+)*G/ {printf "%s ", $1 ;for (j = 2; j < NF+1; j++) printf "%s", $j; print""}' \
| awk 'BEGIN {FS="G "} {if ($1>3) print $0}' | less

Для поиска парок измеряемых гигабайтами (>1Gb):

du -h -d 7 /home | grep "^ *[0-9]*G"

Замена части строк в текстовых файлах находящихся в одной директории

Мне понадобилось заменить время в расписании находящихся во многих текстовых файлах части строк вида: "00:20", "00:30", "00:40", "00:50" на тоже время плюс 2 мин то есть "00:22" и т.д. Это сделал скрипт:

find ./ -type f | sed "s/\.\///g" | \
awk '{system ("cat \""$0"\" | sed s/:20/:22/g | sed s/:30/:32/g | sed s/:40/:42/g | sed s/:50/:52/g > \"../new/"$0"\"")}'

Результат помещается в папку ../new/

Удаление пробелов и табуляций в конце строки во всех файлах директории (рекурсивно)

Для этого посмотрим какие расширения файлов есть в папках:

find ./ -type f | grep -v "^.*.git" | sed 's/.*\.//' | sort | uniq

Предположим нам требуются только файлы с расширением php, txt, html и еще не надо обрабатывать каталог .git

find ./ -type f -name "*.php" -o -name "*.txt" -o -name "*.html" \
| sed "s/\.\///g" | grep -v "^.*.git" \
| awk '{system ("cat \""$0"\" | sed \"s/[ \\t]*$//g\" > \"../tmp.file\" && mv \"../tmp.file\" \""$0"\"");}'

Поиск php файлов начинающихся не с "<?php"

В Wordpress темах иногда делаю ошибку, в начало файла случайно вставляю пустую строку или случайные символы, возможно даже не печатные, а все php файлы должны начинаться с <?php

Этот короткий скрипт ищет файлы которые начинаются не с <?php

find ./ -type f | grep -i php$ \
| awk '{f=$0;  getline s<$0; c=substr(s,1,5); if (c != "<?php") {print "Символы:\""c"\""; print "Строка:"s; print "Файл:"f;}}'

Если "Символы" и "Строка" отличаются, значит есть не печатные символы.

Удаление переносов строк в стиле windows всех файлах директории (рекурсивно)

Мы будем удалять только в php файлах, если требуется большее типов файлов смотри выше

find ./ -type f -name "*.php"\
| sed "s/\.\///g" | grep -v "^.*.git" \
| awk '{system ("cat \""$0"\" | sed \"s/\\r\\$//g\" > \"../tmp.file\" && mv \"../tmp.file\" \""$0"\"");}'

Создание html таблицы по времени создания файлов в директории

Скрипт1:

# подсчитывает кол-во файлов в директории и всех вложенных папках осзданных в октябре
# и формирует таблицу формата html
# по вертикали месяца, по горизонтали 24 часа с интервалом в минуту на пересечении колво файлов созданных за эту  минуту.
echo "<html><table border=1>"
find ./ -type f | awk '{system ("ls -la "$0" | grep окт")}' | tr ":" " " \

| awk 'BEGIN {printf " "; for(j=0;j<=23;j++) {for(k=0;k<=59;k++) printf "%d:%d", j, k}; printf "\n"}{dat[$6+0,$8+0,$9+0]++}END{for(i=1;i<=31;i++) {printf "%d", i; for(j=0;j<=23;j++){for(k=0;k<=59;k++) printf "%d", dat[i,j,k]}; printf "\n"};}'

echo "</table></html>"

Скрипт2:

# подсчитывает кол-во файлов в директории и всех вложенных папках осзданных в октябре,
# причем файлы должны содержать текст "fmreklama.ru"
# и формирует таблицу формата html
# по вертикали месяца, по горизонтали 24 часа с интервалом в минуту на пересечении колво файлов созданных за эту минуту.
echo "<table><tr>"
find ./ -type f | awk '{system ("ls -la "$0); print $0}' \
| awk '/окт/ {getline; system ("egrep -c \"fmreklama.ru\" \""$0"\""); print $0}' \
| awk '{t=$0; getline; if (t > 0) system ("ls -la "$0" | grep окт")}' | tr ":" " " \

| awk 'BEGIN {printf " "; for(j=0;j<=23;j++) {for(k=0;k<=59;k++) printf "%d:%d", j, k}; printf "\n"}{dat[$6+0,$8+0,$9+0]++}END{for(i=1;i<=31;i++) {printf "%d", i; for(j=0;j<=23;j++) {for(k=0;k<=59;k++) printf "%d", dat[i,j,k]}; printf "\n"};}'

echo "</table></html>"

Подсчёт количества файлов в заданной директории

Скрипт1:

echo $1
#
find $1 -type d -depth 1 | awk '{print $0; system("find \""$0"\" | /home/count1.sh")}'

Скрипт2:

#
awk 'BEGIN{k=0}{k=k+1}END{print k}'

Переименование файлов с преобразованием кодировки (из koi8 в cp1251)

Ключ -c в iconv заставляет iconv пропускает ошибки, символы которые не может преобразовать.

find ./ -type d | awk '{system ("echo \""$0"\" | iconv -c -f koi8-r -t cp1251")}' | awk '{system ("mkdir -p \"../new/"$0"\"")}'
find ./ -type f | awk '{printf $0"====="; system ("echo \""$0"\" | iconv -c -f koi8-r -t cp1251")}' \
| awk 'BEGIN {FS="====="} {system ("mv \""$1"\" \"../new/"$2"\"")}'

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

cp1251toutf-8.sh:

 #!/bin/sh
 #Папка где лежат файлы скрипта, в том чесле и этот файл
 Dscript=/home/rom/test/myscript
 
 #Папка в которую будут складыватся промежуточные файлы
 Dtmp=${Dscript}/tmp
 
 #Папка в которой будут переименовыватся файлы и папки
 Dwork=/home/rom/test/temp
 
 #Папка в которой создается дерево директорий и переносит файлы
 Dresult=/home/rom/test/new

 #Создание папки для промежуточных результатов
 mkdir -p ${Dtmp}

 cd ${Dwork}
 #Создание списка папок и файлов (удалите -follow если не надо следовать символическим ссылкам)
 find ./ -follow -type d > ${Dtmp}/folders.txt
 find ./ -follow -type f > ${Dtmp}/files.txt
 
 #Комментируем проценты
 cat ${Dtmp}/folders.txt | sed -f ${Dscript}/scr_per.sed > ${Dtmp}/scr_folders.txt
 cat ${Dtmp}/files.txt | sed -f ${Dscript}/scr_per.sed > ${Dtmp}/scr_files.txt
 
 #создаем файл в котором в одной строке ИСХОДНОЕ_НАЗВАНИЕ:::::::ДАТАСОЗДАНИЯ:::::::НОВОЕ_НАЗВАНИЕ
 cat ${Dtmp}/scr_folders.txt \
 | awk -v scrdol="${Dscript}/scr_dol.sed" -v scrper="${Dscript}/scr_per.sed" '{system ("echo -n \""$0":::::::\" | sed -f "scrdol" | tr -d \"\n\"; stat -f %Sm -t %Y%m%d%H%M "$0" | tr -d \"\n\"; echo -n \":::::::\"; echo "$0" | iconv -c -f cp1251 -t utf-8 | sed -f "scrper)}' \
 > ${Dtmp}/print_folders.txt
 cat ${Dtmp}/scr_files.txt \
 | awk -v scrdol="${Dscript}/scr_dol.sed" -v scrper="${Dscript}/scr_per.sed" '{system ("echo -n \""$0":::::::\" | sed -f "scrdol" | tr -d \"\n\"; stat -f %Sm -t %Y%m%d%H%M "$0" | tr -d \"\n\"; echo -n \":::::::\"; echo "$0" | iconv -c -f cp1251 -t utf-8 | sed -f "scrper)}' \
 > ${Dtmp}/print_files.txt
 
 #Создаем скрипт для создания папок
 echo "cd ${Dwork}" > ${Dtmp}/mkdir_my.sh
 cat ${Dtmp}/print_folders.txt \
 | awk -v dresult=${Dresult} 'BEGIN{FS=":::::::"}{print ("mkdir -p "dresult"/"$3)}' \
 >> ${Dtmp}/mkdir_my.sh
 
 #Создаем скрипт для переноса фалов
 echo "cd ${Dwork}" > ${Dtmp}/mv_my.sh
 cat ${Dtmp}/print_files.txt \
 | awk -v dresult=${Dresult} 'BEGIN{FS=":::::::"}{print ("mv "$1" "dresult"/"$3)}' \
 >> ${Dtmp}/mv_my.sh
 
 #Создаем скрипт востанавления время создания каждой папки
 echo "cd ${Dresult}" > ${Dtmp}/touch_my.sh
 cat ${Dtmp}/print_folders.txt \
 | awk 'BEGIN{FS=":::::::"}{print ("touch -t"$2" "$3)}' >> ${Dtmp}/touch_my.sh
 
 #Выполняем скрипты
 sh ${Dtmp}/mkdir_my.sh
 sh ${Dtmp}/mv_my.sh
 sh ${Dtmp}/touch_my.sh

scr_dol.sed:

 s/\$/\\\$/g
 s/`/\\\`/g

scr_per.sed:

 s/ /\\\ /g
 s/\'/\\\'/g
 s/\$/\\\$/g
 s/\!/\\\!/g
 s/(/\\\(/g
 s/)/\\\)/g
 s/{/\\\{/g
 s/}/\\\}/g
 s/&/\\\&/g
 s/`/\\\`/g
 s/;/\\\;/g

Переформатируем файлы сайта в папке rrv из кодировки cp-1251 в utf-8

Создаем копию дерева деорикторий в папке utf-8

mkdir ./utf-8 && cp -r ./rrv ./utf-8/

Ищем все возможные расширения

find ./rrv/utf-8/mayak -type f | grep -v \.svn | sed 's/.*\.//' \
| sort | awk '{printf ("| grep -v "$0"$ ")}'

Потом удаляем ненужные типы расширений (например картинки) копируем и вставляем в следующую строку

find ./rrv -type f | grep -v svn | grep -v JPG$ \                                                                                                    
| grep -v css$ | grep -v dataModel$ | grep -v db$ | grep -v gif$ | grep -v htc$ \                                                                      
| grep -v jpg$ | grep -v old$ | grep -v png$ | grep -v tar$ | grep -v tpl$ \                                                                           
| grep -v ttf$ | grep -v wsdlDataModel$ \                                                                                                              
| awk '{system ("iconv -c -t UTF-8 -f CP1251 \""$0"\" > \"./utf-8/"$0"\"")}'

Проверка работоспособности HTTP сервера

Для проверки запускаем по крону скрипт:

(sleep 2 && echo "HEAD / HTTP/1.0" && echo && sleep 2) \
| telnet r-info.net 80 2>/dev/null | grep "HTTP/.*\..* 200 OK" \
| awk 'BEGIN{k=0}{if ($0~" 200 OK") k=1}END{if (k==0) print "Сервер r-info.net недоступен!"}'

Не забудем указать полные пути для всех команд: awk, telnet, ...

Результатом работы скрипта будет письмо пользователю от которого был запущен скрипт.

Скрипт, который переворачивает файл (последняя строка станет первой и т.д.)

cat file.txt | awk 'BEGIN {FS="\n"; RS=""; OFS=""} {for (i=NF; i>0; i--) print $i;}'

В линуксе для этой цели есть утилита tac

Скрипт парсит html

parser.sh

#!/bin/sh
#Скрипт делает следующее:
#1. Определяет путь до parser.sed, скрипта написанного на sed который должен находится в той же директории, что и этот скрипт
#2. Определяет дату на день вчерашний в виде 20090312 (год месяц день)
#3. Скачивает вчерашний плейлист европы+ с сайта http://www.moskva.fm/stations/FM_106.2/20090312
#4. Выделяет парсит с помощью скрипта (parser.sed) написанного на sed html-файл выделяя время выхода в эфир, исполнителя и песню
#5. Сортирует в обратном порядке (т.к. там плейлист в обратном порядке) делая 2 строчки на каждую песню
#     первая строка время выхода, вторая ИСПОЛНИТЕЛЬ - НАЗВАНИЕ ПЕСНИ
#6. Переводим кодировку из utf-8 в koi8-r
PATHSCRIPT=`echo $0 | /usr/bin/sed -n "s/parser.sh$/parser.sed/p"`
D=`date +%s | /usr/bin/awk '{k=$1-86400; system ("date -r "k" +%Y%m%d")}'`
/usr/local/bin/lynx -accept_all_cookies -source http://www.moskva.fm/stations/FM_106.2/$D | \
/usr/bin/sed -n -f $PATHSCRIPT | \
/usr/bin/awk 'BEGIN {FS="\n"; RS=""; OFS=""} {for (i=NF; i>0; i=i-3) print ($(i-2)"\n"$i" - "$(i-1));}' | \
/usr/local/bin/iconv -с -f utf-8 -t koi8-r > 1.txt

parser.sed

/^ / { s/[ ]*//

s/<\/td>//
p
}
/<a href="\/artist\/.*" class="artist">.*<\/a><\/p>/ {
s/[     ]*<a href="\/artist\/.*" class="artist">//
s/<\/a><\/p>//
p
}
/onclick=\"return manageSong(this)\"/{
s/[     ]*<a href="http:\/\/www\.moskva\.fm\/artist\/.*" class="song">//
s/<\/a> <a href=".*" class="add" onclick="return manageSong(this)"><\/a>
// p }

Возможности egrep, выделение последлвательности TTH

Не много не в тему, но может пригодится.
Имеем строку вида:

magnet:?xt=urn:tree:tiger:TL5GMCI5ZSYCRKZY35COUOPNZC47DWOTEU44UKQ&xl=1465516032&dn=The%20international.avi

Требуется вычленить tth сумму.
Вариант 1. (Сложный):

$ echo "magnet:?xt=urn:tree:tiger:TL5GMCI5ZSYCRKZY35COUOPNZC47DWOTEU44UKQ&xl=1465516032&dn=The%20international.avi" \
| awk 'BEGIN{FS="urn:tree:tiger:%7C&xl="}{print $2}'

TL5GMCI5ZSYCRKZY35COUOPNZC47DWOTEU44UKQ

Вариант 2. (Простой используя egrep)

$ echo "magnet:?xt=urn:tree:tiger:TL5GMCI5ZSYCRKZY35COUOPNZC47DWOTEU44UKQ&xl=1465516032&dn=The%20international.avi" \
| egrep -o [A-Z0-9]{39}

TL5GMCI5ZSYCRKZY35COUOPNZC47DWOTEU44UKQ

Загрузка системы на FreeBSD в %

/sbin/sysctl vm.loadavg | /usr/bin/awk '{printf("%d\n", $4*100)}'

Любителям калькулятора dc посвещается:

sysctl vm.loadavg | awk '{printf("2k 100 %s * p", $4)}' | sed "s/,/./g" | dc | awk 'BEGIN{FS="."}{print $1}'

Получение списка файлов в директории в случайном порядке

#!/bin/sh
#Подготавливаем псевдослучайные значения для srand из двух чисел сек. и мин.
T1=`/bin/date +%S%M`
T2=`/bin/date +%M%S`
Подсчитываем кол-во файлов в директории
L=`ls | wc -l | sed "s/ //g"`
# Собственно получаем случайный список путем замены каждого значения списка со случайной позицией из этого же списка
ls | awk '{printf $0"-=-=-=-=-"}' \
| awk -v s=$T1 -v m=$T2 -v l=$L 'BEGIN{FS="-=-=-=-=-"; srand((s+1)*(m+1)) }for (i = 1; i < l; i++){k=int((l-1)*rand()+1); p=$k; $k=$i; $i=p}; for (i = 1; i < l; i++) {printf $i"+"}}'

Кусок скрипта фильтрующий строки содержащие только ip адрес, скрипт сортирует ip адреса и удаляет дубли

cat ip.list | grep "^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$" | sort | uniq

Удобная утилита замены tr

Почитать описание синтаксиса tr

Правильный поиск всех пользователей зарегистрированных в системе

getent passwd | awk 'BEGIN{FS=":"}{print $1}'

Подсчет кол-ва подключений на один порт

sockstat | grep 8000 | wc -l 

Но если каждый клиент создает по 4 подключения на 1 порт, и еще сам процесс создает четыре сокета на порту 8000, то поручается, что надо подсчитать кол-во записей порта 8000 поделить на 4 и вычесть 1, реализуем:

sockstat | grep 8000 | wc -l | awk '{system ("expr "$1 " / 4  - 1");}'

"Придумывание" паролей

Возникла потребность придумать пароли для сотен почтовых ящиков. Родилась идея, воспользоватся для генерации паролей, ограниченной десятью символами md5 суммой от имени почтового ящика плюс некоторая фраза (в моем случае "соль"):

cat mail_list.txt | awk '{system ("md5 -s соль"$0)}' \
| awk '{print $4}' | cut -c 1-10 | paste mail_list.txt - \
> mail_pass_list.txt

Дублирование прав доступа

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

Для начала установим права 755 на все папки новой версии:

find /home/site_new -type d -exec chmod a+xr,u+w {} \;

Права на все файлы новой версии:

find /home/site_new -type f -exec chmod a+r,u+w {} \;

Ищем директории доступные для записи группе (www) и устанавливаем на новый движок:

find /home/site -type d \( -perm -2 -o -perm -20 \) \
| awk 'BEGIN{FS="^\."}{system ("chmod g+w \"/home/site_new"$2"\"")}'

Если требуется делаем тоже и для файлов:

find /home/site -type f \( -perm -2 -o -perm -20 \) \
| awk 'BEGIN{FS="^\."}{system ("chmod g+w \"/home/site_new"$2"\"")}'

Еще примеры для find ищем тут:Find - поиск файлов по правам доступа.

Полезное примеры на перле

Perl как замен sed, или perl однострочные скрипты.

Удаление файлов из директории, когда rm ./* выдает ошибку превышения числа файлов

ls | head -n 10000 | awk '{system ("rm ./"$0)}'

Удаление прямых ссылок из движка сайта

В папке vlad находится root директория сайта www.xxx.yyy.zzz.ru требуется удалить в движке сайта кучу прямых ссылок на сам сайт и заменить их относительными.

cd vlad
# Создаем два дерева каталогов из папки vlad
find ./ -type d | awk '{system ("mkdir -p \"../vlad1/"$0"\" \"../vlad2/"$0"\"")}'
# Копируем файлы (симлинки не копируются) 
find ./ -type f | awk '{system ("cp \""$0"\" \"../vlad1/"$0"\"")}'
cd ../vlad1
# Находим файлы содержащие прямые линки и заменяем их относительными помещая их в папку vlad2
egrep -l -i "http://www.xxx.yyy.zzz.ru/" -r ./* \
| awk '{system ("cat \""$0"\" | sed \"s/http:\\\/\\\/www\\\.xxx\\\.yyy\\\.zzz\\\.ru\\\//\\\//g\" |  sed \"s/http:\\\/\\\/xxx\\\.yyy\\\.zzz\\\.ru\\\//\\\//g\" > \"../vlad2/"$0"\"")}'

# Копируем и объединяем исходный каталог и отредактированный, симлинки копируются как есть ( -pR ) 
cp -pR vlad/ vlad3/
cp -pR vlad2/ vlad3/

Реверсия строки

$ cat 1.txt
12345
1.2.3.4.5
1--2.3
$ rev 1.txt 
54321
5.4.3.2.1
3.2--1

Убрать путь и оставить только имена файлов

$ find /folder -type f | sed 's/\/.*\///'

или так

$ find ./ -type f | sed 's/.*\///'

Убрать имя файла и оставить только путь

$ find /folder -type f | awk 'BEGIN{FS="/"}{for (i = 2; i < NF; i++) printf ("/"$i); print ("");  }'

Посмотреть какие разрешения есть в папке (рекурсивно)

$ find ./ -type f | sed 's/.*\.//' | sort | uniq

Если папка содержит git то:

$ find ./ -type f | grep -v \.git | sed 's/.*\.//' | sort | uniq

Понижение регистра имен файлов

$ ls ./ | awk '{printf "mv "$0" "; system ("echo "$0" | tr \"A-Z\" \"a-z\"")}' | awk '{system ($0)}'

Параметры mp3 файла

Используется пакет mp3info, пример надо узнать продолжительность всех композиций в папке /mnt/muz c удалением пути (если есть вложенные папки) в формате, название файла время:

$ find /mnt/muz -type f | grep -i mp3$ | awk '{system ("mp3info -v -p \"%f %m:%02s\n\" \""$0"\"");}'

Восстановление удаленных файлов с файловой системы ntfs с раскладыванием по папкам дня создания файла

Скрипт создает последовательность команд которую потом можно выполнить (например перенаправив вывод (>) в файл out.sh и выполнив потом его)

#ntfsundelete -s -p 100 /dev/sdaX | grep '^[0-9]' \
| awk '{printf ("mkdir -p /home/rrv/drive_mount_dir/"$4"; ntfsundelete -u -i "$1" -o \"/home/rrv/drive_mount_dir/"$4"/");for (i = 6; i < NF; i++) printf ($i" "); print($NF"\"");}'

Матрица словосочетаний слов из двух файлов

Есть два файла 1_words.txt и 1_words.txt, в которых в каждой строке по одному слову, надо составить все словосочетания из этих слов:

$ cat 1_words.txt | awk '{system ("cat 2_words.txt | sed \"s%^%"$1" %\"");}'

Поиск "плохих" php-файлов

Любые символы в php-файлах до <?php в начале строки могут вызывать ошибки, например "Cannot modify header information - headers already sent by" следующий скрипт будет искать такие файлы в текущей (.) директории учитывая вложенные (рерурсивно) и выводить их названия:

find . -type f -regex ".*\.\(php\)" -exec awk 'FNR==1 && !/^</ { print FILENAME ": " $0; }; FNR>1 {nextfile}' {} +

Отчет в РАО из файла

cat "./отчет 3 кв 2015.txt" |\
iconv -c -f cp1251 -t utf-8 |\
grep -v "^---" | grep -v "^Title  " |\
sed "s/^.\{37\}/&===/" | sed "s/^.\{56\}/&===/" | sed "s/^.\{67\}/&===/" |\
sed "s/^.\{78\}/&===/" | sed "s/^.\{105\}/&===/" | sed "s/^.\{143\}/&===/" |\
sed "s/\t/ /g" | sed "s/\r/ /g" | sed "s/  */ /g" |\
awk 'BEGIN{FS=" ==="}{split($3, a, ":"); if ($6!="" && $5!="") print $1"\t"$5"\t"$5"\t"$3"\t"$4*1"\t"(a[1]*60+a[2])*$4"\tпесня\t"$2"\tСобственная фонотека"}' \
> ./rao_отчет_3_кв_2015.cvs

исходный файл (./отчет 3 кв 2015.txt) вида таблицы:

Title                                Artist          Length  Times   Composers               Publisher       Record Label
---------------------------------------------------------------------------------------------------------------------------------
Nothing Like The Rain                2 UNLIMITED     04:39   0015    A.D.Dels, J.P.De Coster ZYX Music                           
Here Without You                     3 DOORS DOWN    03:53   0011    Arnold/Harrell/Henderso UNIVERSAL                           

Тут интересно решение по разбиению таблицы на ячейки с помощью:

sed "s/^.\{37\}/&===/"

Тут 37 это ширина первой ячейки в символах в конец добавляем === для отделения ячейки, 56 это конец второй ячейки с учетом добавленного разделителя "==="

Еще интересный момент в awk:

split($3, a, ":");

Тут переменная $3 в которой находится время композиции в виде 04:39 и получаем массив a[1]=04 и a[2]=39

Заменяем последовательность пробелов одним пробелом:

sed "s/  */ /g"


Преобразование xlsx to csv

gnumeric

Тяжелый вариант:

sudo apt install --no-install-recommends gnumeric

Затем преобразуем:

ssconvert test.xlsx test.csv

Если разделитель "," не устраивает, то используем:

ssconvert -O 'separator=;' --export-type="Gnumeric_stf:stf_assistant" test.xlsx test.csv

xlsx2csv

Легкий вариант написанный на питоне, но у меня не получилось нормально преобразовать временные ячейки, ни как не хотел выводить в формате HH:MM:SS выводил только в HH:MM но если это не важно, то это лучший вариант.

sudo apt install xlsx2csv

Преобразование:

xlsx2csv -i -d ";" test.xlsx > test.csv