На 32-разрядной архитектуре диапазон адресного пространства для обращения к RAM:
0x00000000 - 0xffffffff
или 4'294'967'295
(4 ГБ).
Ядро Linux распадается, это 3/1 (мог также быть 2/2 или 1/3 1) в пространство пользователя (верхняя память) и пространство ядра (низкая память) соответственно.
Диапазон пространства пользователя:
0x00000000 - 0xbfffffff
Каждый недавно порожденный пользовательский процесс получает адрес (диапазон) в этой области. Пользовательские процессы обычно недоверяемы и поэтому запрещаются получить доступ к пространству ядра. Далее, их считают несрочными, как правило, ядро пытается задержать выделение памяти к тем процессам.
Диапазон пространства ядра:
0xc0000000 - 0xffffffff
Ядро процессы получает свой адрес (диапазон) здесь. Ядро может непосредственно получить доступ к этому 1 ГБ адресов (хорошо, не полный 1 ГБ, существует 128 МБ, зарезервированных для доступа верхней памяти).
Процессам, порожденным в пространстве ядра, доверяют, срочные и принятым безошибочный, запрос памяти обрабатывается мгновенно.
Каждый процесс ядра может также получить доступ к диапазону пространства пользователя, если он хочет. И достигнуть этого, ядро отображает адрес от пространства пользователя (верхняя память) к ее пространству ядра (низкая память), упомянутых выше 128 МБ особенно резервируются для этого.
1, Является ли разделение 3/1, 2/2, или 1/3 управляют CONFIG_VMSPLIT_...
опция; можно, вероятно, проверить под /boot/config*
видеть, какая опция была выбрана для Вашего ядра.
В Vim можно использовать [и] быстро перемещаться в ближайшую несоответствующую скобку типа, вводимого в следующее нажатие клавиши.
Таким образом [{заберет Вас до ближайшего несопоставленного "{";]), взял бы Вас вперед к ближайшему несопоставленному")", и так далее.
Обновление 2:
Следующий сценарий теперь распечатывает номер строки и столбец несогласованной скобки. Это обрабатывает один тип скобок на сканирование (т.е.' []'' <>' '{}'' ()'...)
Сценарий определяет первую, несопоставленную правую скобку или первую из любой непарной левой скобки... При обнаружении erroe это выходит с номерами строки и номерами столбцов
Вот некоторый демонстрационный вывод...
File = /tmp/fred/test/test.in
Pair = ()
*INFO: Group 1 contains 1 matching pairs
ERROR: *END-OF-FILE* encountered after Bracket 7.
A Left "(" is un-paired in Group 2.
Group 2 has 1 un-paired Left "(".
Group 2 begins at Bracket 3.
see: Line, Column (8, 10)
----+----1----+----2----+----3----+----4----+----5----+----6----+----7
000008 ( ) ( ( ( ) )
Вот сценарий...
#!/bin/bash
# Itentify the script
bname="$(basename "$0")"
# Make a work dir
wdir="/tmp/$USER/$bname"
[[ ! -d "$wdir" ]] && mkdir -p "$wdir"
# Arg1: The bracket pair 'string'
pair="$1"
# pair='[]' # test
# pair='<>' # test
# pair='{}' # test
# pair='()' # test
# Arg2: The input file to test
ifile="$2"
# Build a test source file
ifile="$wdir/$bname.in"
cp /dev/null "$ifile"
while IFS= read -r line ;do
echo "$line" >> "$ifile"
done <<EOF
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
[ ] [ [ [
< > <
< >
< > > >
----+----1----+----2----+----3----+----4----+----5----+----6
{ } { } } } }
( ) ( ( ( ) )
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
EOF
echo "File = $ifile"
# Count how many: Left, Right, and Both
left=${pair:0:1}
rght=${pair:1:1}
echo "Pair = $left$rght"
# Make a stripped-down 'skeleton' of the source file - brackets only
skel="/tmp/$USER/$bname.skel"
cp /dev/null "$skel"
# Make a String Of Brackets file ... (It is tricky manipulating bash strings with []..
sed 's/[^'${rght}${left}']//g' "$ifile" > "$skel"
< "$skel" tr -d '\n' > "$skel.str"
Left=($(<"$skel.str" tr -d "$left" |wc -m -l)); LeftCt=$((${Left[1]}-${Left[0]}))
Rght=($(<"$skel.str" tr -d "$rght" |wc -m -l)); RghtCt=$((${Rght[1]}-${Rght[0]}))
yBkts=($(sed -e "s/\(.\)/ \1 /g" "$skel.str"))
BothCt=$((LeftCt+RghtCt))
eleCtB=${#yBkts[@]}
echo
if (( eleCtB != BothCt )) ; then
echo "ERROR: array Item Count ($eleCtB)"
echo " should equal BothCt ($BothCt)"
exit 1
else
grpIx=0 # Keep track of Groups of nested pairs
eleIxFir[$grpIx]=0 # Ix of First Bracket in a specific Group
eleCtL=0 # Count of Left brackets in current Group
eleCtR=0 # Count of Right brackets in current Group
errIx=-1 # Ix of an element in error.
for (( eleIx=0; eleIx < eleCtB; eleIx++ )) ; do
if [[ "${yBkts[eleIx]}" == "$left" ]] ; then
# Left brackets are 'okay' until proven otherwise
((eleCtL++)) # increment Left bracket count
else
((eleCtR++)) # increment Right bracket count
# Right brackets are 'okay' until their count exceeds that of Left brackets
if (( eleCtR > eleCtL )) ; then
echo
echo "ERROR: MIS-matching Right \"$rght\" in Group $((grpIx+1)) (at Bracket $((eleIx+1)) overall)"
errType=$rght
errIx=$eleIx
break
elif (( eleCtL == eleCtR )) ; then
echo "*INFO: Group $((grpIx+1)) contains $eleCtL matching pairs"
# Reset the element counts, and note the first element Ix for the next group
eleCtL=0
eleCtR=0
((grpIx++))
eleIxFir[$grpIx]=$((eleIx+1))
fi
fi
done
#
if (( eleCtL > eleCtR )) ; then
# Left brackets are always potentially valid (until EOF)...
# so, this 'error' is the last element in array
echo
echo "ERROR: *END-OF-FILE* encountered after Bracket $eleCtB."
echo " A Left \"$left\" is un-paired in Group $((grpIx+1))."
errType=$left
unpairedCt=$((eleCtL-eleCtR))
errIx=$((${eleIxFir[grpIx]}+unpairedCt-1))
echo " Group $((grpIx+1)) has $unpairedCt un-paired Left \"$left\"."
echo " Group $((grpIx+1)) begins at Bracket $((eleIxFir[grpIx]+1))."
fi
# On error, get Line and Column numbers
if (( errIx >= 0 )) ; then
errLNum=0 # Source Line number (current).
eleCtSoFar=0 # Count of bracket-elements in lines processed so far.
errItemNum=$((errIx+1)) # error Ix + 1 (ie. "1 based")
# Read the skeketon file to find the error line-number
while IFS= read -r skline ; do
((errLNum++))
brackets="${skline//[^"${rght}${left}"]/}" # remove whitespace
((eleCtSoFar+=${#brackets}))
if (( eleCtSoFar >= errItemNum )) ; then
# We now have the error line-number
# ..now get the relevant Source Line
excerpt=$(< "$ifile" tail -n +$errLNum |head -n 1)
# Homogenize the brackets (to be all "Left"), for easy counting
mogX="${excerpt//$rght/$left}"; mogXCt=${#mogX} # How many 'Both' brackets on the error line?
if [[ "$errType" == "$left" ]] ; then
# R-Trunc from the error element [inclusive]
((eleTruncCt=eleCtSoFar-errItemNum+1))
for (( ele=0; ele<eleTruncCt; ele++ )) ; do
mogX="${mogX%"$left"*}" # R-Trunc (Lazy)
done
errCNum=$((${#mogX}+1))
else
# errType=$rght
mogX="${mogX%"$left"*}" # R-Trunc (Lazy)
errCNum=$((${#mogX}+1))
fi
echo " see: Line, Column ($errLNum, $errCNum)"
echo " ----+----1----+----2----+----3----+----4----+----5----+----6----+----7"
printf "%06d $excerpt\n\n" $errLNum
break
fi
done < "$skel"
else
echo "*INFO: OK. All brackets are paired."
fi
fi
exit
Line, Column (8, 10)
неважно, какой файл я примеряю его. Также mogXCt=${#mogX}
устанавливается, но не используется где угодно.
– Clayton Dukes
08.11.2017, 05:39
Наилучшим вариантом является vim/gvim, как определено Shadur, но если Вы хотите сценарий, можно проверить мой ответ на подобный вопрос на Переполнении стека. Я повторяю свой целый ответ здесь:
Если то, что Вы пытаетесь сделать, относится к языку общего назначения, то это - нетривиальная проблема.
Запускаться с Вас должно будет волноваться о комментариях и строках. Если Вы захотите проверить это на языке программирования, который использует регулярные выражения, то это сделает Ваши поиски тяжелее снова.
Таким образом, прежде чем я могу войти и дать Вам любой совет относительно Вашего вопроса, я должен знать пределы Вашей проблемной области. Если можно гарантировать, что нет никаких строк, никаких комментариев и никаких регулярных выражений для волнения о - или более в общем нигде в коде, что скобки могут возможно использоваться кроме для использования, на которое Вы проверяете, что они сбалансированы - это сделает жизнь намного более простой.
Знание языка, который Вы хотите проверить, было бы полезно.
Если я беру гипотезу, что нет никакого шума, т.е. что все скобки являются полезными скобками, моя стратегия была бы повторяющейся:
Я просто искал бы и удалил бы всех внутренних пар скобки: те, которые не содержат скобок внутри. Это лучше всего сделано путем сворачивания всех строк к единственной длинной линии (и найдите механизм к добавить ссылки строки, должны, необходимо получить ту информацию). В этом случае поиск и замена довольно просты:
Это требует массива:
B["("]=")"; B["["]="]"; B["{"]="}"
И цикл через те элементы:
for (b in B) {gsub("[" b "][^][(){}]*[" B[b] "]", "", $0)}
Мой тестовый файл следующие:
#!/bin/awk
($1 == "PID") {
fo (i=1; i<NF; i++)
{
F[$i] = i
}
}
($1 + 0) > 0 {
count("VIRT")
count("RES")
count("SHR")
count("%MEM")
}
END {
pintf "VIRT=\t%12d\nRES=\t%12d\nSHR=\t%12d\n%%MEM=\t%5.1f%%\n", C["VIRT"], C["RES"], C["SHR"], C["%MEM"]
}
function count(c[)
{
f=F[c];
if ($f ~ /m$/)
{
$f = ($f+0) * 1024
}
C[c]+=($f+0)
}
Мой полный сценарий (без ссылки строки) следующие:
cat test-file-for-brackets.txt | \
tr -d '\r\n' | \
awk \
'
BEGIN {
B["("]=")";
B["["]="]";
B["{"]="}"
}
{
m=1;
while(m>0)
{
m=0;
for (b in B)
{
m+=gsub("[" b "][^][(){}]*[" B[b] "]", "", $0)
}
};
print
}
'
Вывод того сценария останавливается на самом внутреннем недопустимом использовании скобок. Но остерегайтесь: 1/этот сценарий не будет работать со скобками в комментариях, регулярных выражениях или строках, 2/это, не сообщает, где в исходном файле проблема расположена, 3/, хотя он удалит все симметричные пары, он останавливается в самых внутренних состояниях ошибки и сохраняет все englobbing скобки.
Точка 3/является, вероятно, годным для использования результатом, хотя я не уверен в механизме создания отчетов, Вы имели в виду.
Точку 2/относительно легко реализовать, но берет больше, чем работа нескольких минут для создания, таким образом, я оставлю ее до Вас для выяснения.
Точка 1/является хитрой, потому что Вы вводите совершенно новую область конкуренции иногда вкладываемого начала и окончаний или специальных правил заключения в кавычки для специальных символов...