Como apontado por taliezin , seu erro foi usar $
para expandir path
ao imprimir. Ao contrário de bash
ou make
, awk
não usa o $
para expandir nomes de variáveis para seu valor, mas para se referir aos campos de uma linha (semelhante a perl
).
Então, apenas removendo isso, seu código funcionará:
BEGIN{
path=""
}
{
if ($1 ~ /\:/)
{
sub(/\:/,"",$1)
if (substr($1, length,1) ~ /\//)
{
path=$1;
}
else
{
path=$1"/"
}
}
else if (length($0) == 0)
{}
else
print path$1
}
No entanto, isso não é realmente uma solução awk
ish:
Primeiro de tudo, não há necessidade de inicializar path
em uma regra de BEGIN
, padrão de variáveis não definidas para ""
ou 0
, dependendo do contexto.
Além disso, qualquer script awk
consiste em padrões e ações , o primeiro informando quando , o último o que fazer.
Você tem uma ação que é sempre executada (vazio padrão ) e internamente usa condicionais (aninhados) para decidir o que fazer.
Minha solução ficaria assim:
# BEGIN is actually a pattern making the following rule run only once:
# That is, before any input is read.
BEGIN{
# Split lines into chunks (fields) separated by ":".
# This is done by setting the field separator (FS) variable accordingly:
# FS=":" # this would split lines into fields by ":"
# Additionally, if a field ends with "/",
# we consider this part of the separator.
# So fields should be split by a ":" that *might*
# be predecessed by a "/".
# This can be done using a regular expression (RE) FS:
FS="/?:" # "?" means "the previous character may occur 0 or 1 times"
# When printing, we want to join the parts of the paths by "/".
# That's the sole purpose of the output field separator (OFS) variable:
OFS="/"
}
# First we want to identify records (i.e. in this [default] case: lines),
# that contain(ed) a ":".
# We can do that without any RE matching, since records are
# automatically split into fields separated by ":".
# So asking >>Does the current line contain a ":"?<< is now the same
# as asking >>Does the current record have more than 1 field?<<.
# Luckily (but not surprisingly), the number of fields (NF) variable
# keeps track of this:
NF>1{ # The follwoing action is run only if are >1 fields.
# All we want to do in this case, is store everything up to the first ":",
# without the potential final "/".
# With our FS choice (see above), that's exactly the 1st field:
path=$1
}
# The printing should be done only for non-empty lines not containing ":".
# In our case, that translates to a record that has neither 0 nor >1 fields:
NF==1{ # The following action is only run if there is exactly 1 field.
# In this case, we want to print the path varible (no need for a "$" here)
# followed by the current line, separated by a "/".
# Since we defined the proper OFS, we can use "," to join output fields:
print path,$1 # ($1==$0 since NF==1)
}
E isso é tudo. Removendo todos os comentários, encurtando o nome da variável e movendo as definições [O]FS
para os argumentos da linha de comando, tudo o que você precisa escrever é:
awk -F'/?:' -vOFS=\/ 'NF>1{p=$1}NF==1{print p,$1}' structure-of-home.cnf