LINUX.ORG.RU

awk, куда же без него

 ,


1

1

Всех приветствую, есть такая задачка... Есть файл checksum, который состоит из 3х столбцов: md5sum, file_name, permission for chmod.

804567c6efce1755d11fc6ebbb263aa7  /mnt/dcu/mysql/bin/mysqld_safe        0755
f7e0baa7e97ea3075afec0e248e85b0d  /mnt/dcu/mysql/bin/mysql_install_db   0755
3388b314d96df3e372135d88b0fd48fb  /mnt/dcu/mysql/bin/mysqladmin 0755
73fdf21d66c328d3eb3c3d042783e1d8  /mnt/dcu/mysql/bin/resolveip  0755
47394f1c3430227b647d7e60d81dbe70  /mnt/dcu/mysql/bin/mysql      0755
00394418de5b9581bcce9ac7a51cff21  /mnt/dcu/mysql/bin/mysqlcheck 0755
338953d9c90ed4fc5ddd107af797fd1e  /mnt/dcu/mysql/bin/mysqldump  0755
5efb889b87b305e658db83ba3fe83bb8  /mnt/dcu/mysql/bin/myisamchk  0755

Хочется написать 2 конструкции: 1) которую я уже сделал - чтобы awk пробегал по строчкам, выбирал $3 и делал chmod $3 $2.

awk '{ if ($3 != "") { print | "chmod " $3 " "$2} }' checksum

2) задача - надо попробовать сделать так: чтобы awk брал $2, делал ему md5sum и сравнивал с $1. Если всё ок, то сообщал об этом. Написал такую штуку:

awk '{ if ($3 != "") { 
	if ( { print | "md5sum " $2} == $1) { 
		print "md5sum is correct"; 
		} 
	else { 
		print "md5sum is incorrect";
		}
	}
}' checksum

Но потом понял, что она у меня не сработает, потому что md5sum выдаётся в таком виде:

[root@localhost:]# grep mysql checksum |  awk '{print | "md5sum " $2}'
804567c6efce1755d11fc6ebbb263aa7  /mnt/dcu/mysql/bin/mysqld_safe
f7e0baa7e97ea3075afec0e248e85b0d  /mnt/dcu/mysql/bin/mysql_install_db
3388b314d96df3e372135d88b0fd48fb  /mnt/dcu/mysql/bin/mysqladmin
00394418de5b9581bcce9ac7a51cff21  /mnt/dcu/mysql/bin/mysqlcheck
47394f1c3430227b647d7e60d81dbe70  /mnt/dcu/mysql/bin/mysql
338953d9c90ed4fc5ddd107af797fd1e  /mnt/dcu/mysql/bin/mysqldump
beb812183e57b5dc59a8694f8ddba851  /mnt/dcu/mysql/bin/my_print_defaults
73fdf21d66c328d3eb3c3d042783e1d8  /mnt/dcu/mysql/bin/resolveip
5efb889b87b305e658db83ba3fe83bb8  /mnt/dcu/mysql/bin/myisamchk

Т.е. мне надо output от print опять пропускать через awk и выделять 1 столбец и смотреть если всё ок (мне почему то кажется что это можно сделать попроще)

Просьба варианты вида

for file in $(awk '{print $2}' checksum); do
	VALID_MD5=$(grep $file  checksum  | awk '{print $1}')
	CURRENT_MD5=$(/usr/bin/md5sum $file | awk '{print $1}')
	if [ "$VALID_MD5" = "$CURRENT_MD5" ] ; then
		echo "File $file has correct md5sum"
	else
		echo "md5sum for file $file is incorrect"
	fi
done

не предлагать.

потому что при попытке найти файл /mnt/dcu/mysql/bin/mysql grep выдаст сразу несколько вариантов и мне пришлось от него отказаться, да и делается это намного медленнее.(например 1 задачу, когда я переписал на awk - скорость увеличилась в 4 раза)


при попытке найти файл /mnt/dcu/mysql/bin/mysql grep выдаст сразу несколько вариантов

А добавить в grep символ конца строки?

kdask
()
Ответ на: комментарий от kdask

с ключом помогло, спасибо.

Правда всё равно остаётся вопрос об оптимизации скорости выполнения. Именно поэтому и пробую переписать на awk.

Входящий файл около 5000 строк, поэтому скорость существенно уменьшается, например для 1 варианта решения.

Aidjek
() автор топика

Я думаю, как-то так должно сработать:

awk '{ if ($3 != "") {
        oldsum = $1
        ("md5sum " $2) | getline #Твои $0, $1 и проч. перезаписались
	if ( oldsum == $1) { 
		print "md5sum is correct"; 
		} 
	else { 
		print "md5sum is incorrect";
		}
	}
}' checksum

proud_anon ★★★★★
()
Последнее исправление: proud_anon (всего исправлений: 2)
Ответ на: комментарий от proud_anon

Спасибо огромное, всё работает.

Не подумал про перезапись локальных переменных.

Aidjek
() автор топика
Ответ на: комментарий от aol

проведя сравнительное тестирование всех предложенных вариантов, я получил такие цифры:

for 
real 1m 3.01s 
user 0m 31.76s 
sys 0m 26.07s

awk 
real 0m 43.29s 
user 0m 11.92s 
sys 0m 26.64s

md5sum -с 
real 0m 40.12s 
user 0m 13.30s 
sys 0m 22.42s 

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

Aidjek
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.