zepete: (Default)
[personal profile] zepete
Для редактирования файлов "ini" из программы bash/dash создал такой "скрипт". Для работы требует наличия sed. Содержит следующие функции:

INI_TestFile filename commentsymbol - проверка на корректность конфигурационного файла;
INI_UnCommentKey FileName Section Key Comment CommentSymbol - удаляет символ комментария перед определением ключа;
INI_UnCommentKeys FileName Section CommentSymbol comment Key1 Key2....... - удаление символа комментария перед несколькиими ключами;
INI_ReadKey FileName Section Key CommentSymbol - читать значение ключа;
INI_TestExistKey FileName Section Key CommentSymbol - проверка наличия ключа в конфигурационном файле;
INI_TestExistSection FileName Section CommentSymbol - проверка наличия секции в конфигурационном файле;
INI_WriteKey FileName Section Key Value comment CommentSymbol - изменение значения ключа

Тескт под катом.
value=""
IFS=""
quote='"'
apostrophe="'"

INI_DivideOnZero ()
{
	local zero=0
	return $(( zero/zero ))
}

#INI_Terminate message
INI_Terminate ()
{
	echo $1
	INI_DivideOnZero
}

#VarDoubleSlash text
VarDoubleSlash ()
{
	if [ $# -ne 1 ] ; then  INI_Terminate "bad number of parameter VarDoubleSlash" ; fi
	value=$(printf %s "$1" | sed -E 's/([\\/])/\\\1/g')
	return $?	
}

VarDoubleBackSlash
VarDoubleBackSlash ()
{
	if [ $# -ne 1 ] ; then  INI_Terminate "bad number of parameter VarDoubleBackSlash" ; fi
	value=$(printf %s "$1" | sed -E 's/\\/\\\\/g')
	return $?	
}
VarDoubleDiv ()
{
	if [ $# -ne 1 ] ; then  INI_Terminate "bad number of parameter VarDoubleDiv" ; fi
	value=$(printf %s "$1" | sed -E 's/\//\\\//g')
	return $?	
}


INI_Shielding()
{
	if [ $# -ne 1 ] ; then INI_Terminate "bad number of parameter INI_Shielding" ; fi
	printf %s $1 | sed -E 's/(\[|\]|[.*|+?$^{}()&\\\/])/\\\1/g'
	if [ $? -ne 0 ] ; then INI_Terminate "INI_Shielding: bad sed" ; fi
}

#INI_TestFile filename commentsymbol
INI_TestFile ()
{
	if [ $# -lt 1 ] ; then  INI_Terminate "bad number of parameter INI_TestFile" ; fi
	if [ $# -gt 2 ] ; then  INI_Terminate "bad number of parameter INI_TestFile" ; fi
	if [ ! -f $1 ] ; then return 1 ; fi # нет конфигурационного файла
	local CS="#"
	if [ ${#2} -eq 1 ] ; then CS=$2 ; fi

	if ! sed -n "1 q" $1 ; then return 2 ; fi # обработка sed невозможна
	#проверка на строки неправильного формата
	if [ "BAD" = "$(sed -En "/^[[:blank:]]*($CS.*)*$/b good\
		;/^[[:blank:]]*\[[[:blank:]]*[^$CS[:blank:]]+[^$CS]*\][[:blank:]]*($CS.*)*$/b good\
		;/^([[:blank:]]*[^$CS[:blank:]]+[[:blank:]]*)*=.*$/b good\
		;s/^.*$/BAD/ ; p ; q ; :good" $1)" ] ; then return 3 ; fi
	if [ "BAD" = "$(sed -En "1,/^[[:blank:]]*\[[[:blank:]]*[^$CS[:blank:]]+[^$CS]*\][[:blank:]]*($CS.*)*$/{\
	/^([[:blank:]]*[^$CS[:blank:]]+[[:blank:]]*)*=.*$/{s/^.*$/BAD/;p;q}}" $1)" ] ; then
		return 4 # есть ключи перед оапределением секции
	fi
	return 0
}

#INI_UnCommentKey FileName Section Key Comment CommentSymbol
INI_UnCommentKey ()
{
	local section=$(INI_Shielding "$2")
	local key=$(INI_Shielding "$3")
	local CS="#"
	local C=""
	if [ $# -lt 3 ] ; then  INI_Terminate "bad number of parameter INI_UnCommentKey" ; fi
	if [ $# -gt 5 ] ; then  INI_Terminate "bad number of parameter INI_UnCommentKey" ; fi	
	if [ ${#5} -gt 1 ] ; then  INI_Terminate "bad len of CommentSymbol INI_UnCommentKey" ; fi
	if [ ${#5} -eq 1 ] ; then CS=$5 ; fi
	if [ ${#4} -gt 0 ] ; then
		if ! C=$(printf %s "$4" | sed -E "s/(\\\\n)/\1$CS/g;s/^(.)/$CS\1/;s/(.)$/\1\\\\n/") ; then  INI_Terminate "INI_UnCommentKey error exec sed" ; fi
		if ! C=$(printf %s $C | sed -E 's/(\[|\]|[.*|+?$^{}()&])/\\\1/g') ; then   INI_Terminate "INI_UnCommentKey error exec sed" ; fi
	fi

	if INI_TestExistKey $1 $2 $3 $5 ; then
		printf %s "!!!Warning!!! key \"$3\" in section \"$2\" in file \"$1\" already uncomment" ; return 0
	fi
	if [ "YES" != "$(sed -En "/^[[:blank:]]*\[$section\][[:blank:]]*($CS.*)*$/, \
/^[[:blank:]]*\[.*\][[:blank:]]*($CS.*)*$/ \
{/^([[:blank:]]*)$CS+([[:blank:]]*$key[[:blank:]]*\
=[[:blank:]]*(([^$CS[:blank:]]+([[:blank:]]*[^$CS[:blank:]]+)*)*)\
[[:blank:]]*($CS.*)*)$/ {s/^.*$/YES/ ;p ;q}}" $1)" ] ; then
		printf %s "!!!Warning!!! comment key \"$3\" in section \"$2\" do not consist in file \"$1\"" ; return 0
	fi
	
	if [ "YES" != "$(sed -En "/^[[:blank:]]*\[$section\][[:blank:]]*($CS.*)*$/,\
/^[[:blank:]]*\[.*\][[:blank:]]*($CS.*)*$/ \
{/^([[:blank:]]*)$CS+([[:blank:]]*$key[[:blank:]]*=[[:blank:]]*\
([^$CS[:blank:]]+([[:blank:]]*[^$CS[:blank:]]+)*)[[:blank:]]*($CS.*)*)$/ {s/^.*$/YES/ ;p ;q}}" $1)" ] ; then
		printf %s "!!!Warning!!! comment key \"$3\" in section \"$2\" in file \"$1\" do not consist any value"
	fi
	
	sed -Ei "/^[[:blank:]]*\[$section\][[:blank:]]*($CS.*)*$/,\
/^[[:blank:]]*\[.*\][[:blank:]]*($CS.*)*$/{\
s/^([[:blank:]]*)$CS+([[:blank:]]*$key[[:blank:]]*=[[:blank:]]*\
(([^$CS[:blank:]]+([[:blank:]]*[^$CS[:blank:]]+)*)*)[[:blank:]]*($CS.*)*)$/$C\1\2/}" $1
	return $?
}

#INI_UnCommentKeys FileName Section CommentSymbol comment Key1 Key2.......
INI_UnCommentKeys ()
{
	local FileName=$1
	local section=$2
	if [ ${#3} -gt 1 ] ; then INI_Terminate "bad len of CommentSymbol INI_UnCommentKeys" ; fi
	local CS=$3
	local comment=$4
	while [ -n "$5" ]
	do
		INI_UnCommentKey $FileName $section $5 $comment $CS
		shift
	done
}

#INI_ReadKey FileName Section Key CommentSymbol
INI_ReadKey ()
{
	local section=$(INI_Shielding "$2")
	local key=$(INI_Shielding "$3")
	local CS="#"
	if [ $# -lt 3 ] ; then  INI_Terminate "bad number of parameter INI_ReadKey" ; fi
	if [ $# -gt 4 ] ; then  INI_Terminate "bad number of parameter INI_ReadKey" ; fi	
	if [ ${#4} -gt 1 ] ; then  INI_Terminate "bad len of CommentSymbol" ; fi
	if [ ${#4} -eq 1 ] ; then CS=$4 ; fi
	if ! INI_TestExistKey $1 $2 $3 $4 ; then return 255 ; fi
	value=$(sed -nE "/^[[:blank:]]*\[$section\][[:blank:]]*($CS.+)*$/,\
/^[[:blank:]]*\[.*\][[:blank:]]*($CS.+)*$/{\
s/^[[:blank:]]*$key[[:blank:]]*=[[:blank:]]*([^$CS[:blank:]]+([[:blank:]]*[^$CS[:blank:]]+)*)[[:blank:]]*($CS.+)*$/\1/p}" $1)
	return $?
}

# INI_TestExistKey FileName Section Key CommentSymbol
INI_TestExistKey ()
{
	local section=$(INI_Shielding "$2")
	local key=$(INI_Shielding "$3")
	local CS="#"
	local begin=""
	local end=""
	
	if [ $# -lt 3 ] ; then  INI_Terminate "bad number of parameter INI_TestExistKey" ; fi
	if [ $# -gt 4 ] ; then  INI_Terminate "bad number of parameter INI_TestExistKey" ; fi	
	if [ ${#4} -gt 1 ] ; then  INI_Terminate "bad len of CommentSymbol" ; fi
	if [ ${#4} -eq 1 ] ; then  CS=$4 ; fi
	if ! INI_TestExistSection $1 $2 $4 ; then return 255 ; fi
	if [ "YES" = "$(sed -nr "/^[[:blank:]]*\[$section\][[:blank:]]*($CS.*)*$/,\
		/^[[:blank:]]*\[.*\][[:blank:]]*($CS.*)*$/{\
		/^[[:blank:]]*$key[[:blank:]]*=.*$/ {s/^.*$/YES/ ;p ;q}}" $1)" ] ; then  return 0 ; fi ;	return 255
}

# INI_TestExistSection FileName Section CommentSymbol
INI_TestExistSection ()
{
	local section=$(INI_Shielding "$2")
	local CS="#"
	if [ $# -lt 2 ] ; then  INI_Terminate "bad number of parameter INI_TestExistSection" ; fi
	if [ $# -gt 3 ] ; then  INI_Terminate "bad number of parameter INI_TestExistSection" ; fi
	if [ ${#3} -gt 1 ] ; then INI_Terminate "bad len of CommentSymbol" ; fi
	if [ ${#3} -eq 1 ] ; then CS=$3 ; fi
	if [ "YES" = "$(sed -nE "/^[[:blank:]]*\[$section\][[:blank:]]*($CS.*)*$/ {s/^.*$/YES/ ;p ;q}" $1)" ]
		then return 0 ; fi
	return 255
}


# INI_WriteKey FileName Section Key Value comment CommentSymbol
INI_WriteKey ()
{
	local CS="#"
	local C=""
	local section=$(INI_Shielding "$2")
	local key=$(INI_Shielding "$3")
	local value=$(INI_Shielding "$4")
	if [ $# -lt 4 ] ; then  INI_Terminate "bad number of parameter INI_WriteKey" ; fi
	if [ $# -gt 6 ] ; then  INI_Terminate "bad number of parameter INI_WriteKey" ; fi
	
	if [ $# -eq 6 ] ; then
		if [ ${#6} -gt 1 ] ; then  INI_Terminate "bad len of CommentSymbol INI_WriteKey" ; fi
		CS=$6
	fi
	
	if [ ${#5} -gt 0 ] ; 	then
		if ! C=$(printf %s "$5" | sed -E "s/(\\\\n)/\1$CS/g;s/^(.)/$CS\1/;s/(.)$/\1\\\\n/") ; then  INI_Terminate "INI_WriteKey error exec sed" ; fi
		if ! C=$(printf %s $C | sed -E 's/(\[|\]|[.*|+?$^{}()&])/\\\1/g') ; then  INI_Terminate "INI_WriteKey error exec sed" ; fi
	fi

	if [ ! -f $1 ] ; then	# если нет конфигурационного файла
		echo "\n" | sed -E "1{s/^.*$/\[$section\]\n$C\n$key=$value/}">$1
		if [ $? -ne 0 ] ; then INI_Terminate "INI_WriteKey error exec sed or write file" ; fi
		return 0
	fi

	if ! INI_TestExistSection $1 $2 $6 ; then
		if [ "YES" != "$(sed -nr "/^[[:blank:]]*$CS+[[:blank:]]*\[$section\]\
[[:blank:]]*($CS.*)*$/ {s/^.*$/YES/ ;p ;q}" $1)" ] ; then	# если нет закомментированной секции, то дописать в конец файла новую секцию
			echo "\n" | sed -E "1{s/^.*$/\n\[$section\]\n$C$key=$value/}">>$1
			if [ $? -ne 0 ] ; then INI_Terminate "INI_WriteKey error exec sed or write file" ; fi
			return 0
		fi
		#удаление комментария с секции
		if ! sed -ri "s/^([[:blank:]]*)$CS+([[:blank:]]*\[$section\][[:blank:]]*($CS.*)*)$/\1\2/" $1 ; then
			INI_Terminate "INI_WriteKey error exec sed or write file"
		fi
	fi

	if ! INI_TestExistKey $1 $2 $3 $6 ;  then # если нет ключа, то проверить на задокументированный ключ
		if [ "YES" = "$(sed -nr "/^[[:blank:]]*\[$section\][[:blank:]]*($CS.*)*$/ \
			,/^[[:blank:]]*\[.*\][[:blank:]]*($CS.*)*$/ \
			{/^[[:blank:]]*$CS+[[:blank:]]*$key[[:blank:]]*=.*$/ {s/^.*$/YES/ ;p ;q}}" $1)" ] ; then 
			# закомментированный ключ есть
			if ! INI_UnCommentKey $1 $2 $3 "" $CS; then # убирание комментария не удалось
				INI_Terminate "INI_WriteKey error INI_UnCommentKey"
			fi
		else
			#ключа нет, добавление нового
			if ! sed -ri "/^[[:blank:]]*\[$section\][[:blank:]]*($CS.*)*$/ a $C$key=$value" $1
			then
				INI_Terminate "INI_WriteKey error sed"
			fi
		fi
	fi
	
	# редактирование ключа
	sed -ri "/^[[:blank:]]*\[$section\][[:blank:]]*($CS.*)*$/ \
		,/^[[:blank:]]*\[.*\][[:blank:]]*($CS.*)*$/ \
		{s/^([[:blank:]]*$key[[:blank:]]*=[[:blank:]]*)(([^$CS[:blank:]]+([[:blank:]]*[^$CS[:blank:]]+)*)*)([[:blank:]]*($CS.*)*)$/$C\1$value\5/}" $1
	if [ $? -ne 0 ] ; then INI_Terminate "INI_WriteKey error" ; fi
}

Profile

zepete: (Default)
zepete

January 2026

S M T W T F S
    1 23
4 56 78910
11121314151617
18192021222324
25262728293031

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 14th, 2026 08:31 am
Powered by Dreamwidth Studios