First of all I'm new to awk so please excuse if it's something simple.
I'm trying to generate a file that contains paths. I'm using for this an ls -LT
listing as well as an awk script:
This is an example of the input file:
vagrant@precise64:/vagrant$ cat structure-of-home.cnf
/home/:
vagrant
/home/vagrant:
postinstall.sh
This would be the expected output:
/home/vagrant
/home/vagrant/postinstall.sh
The awk script should do the following:
- Check whether the line has a
:
in it - If yes allocate the string (without
:
) to a variable ($path
in my case) - If the line is empty print nothing
- If it's not empty and it does not contain a
:
print the$path
and then the current line$0
Here's the script:
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
}
The problem is that when I run the script I get the following mess:
vagrant@precise64:/vagrant$ awk -f format_output.awk structure-of-home.cnf
vagrantvagrant
postinstall.shpostinstall.sh
What am I doing wrong please?
Best Answer
As pointed out by taliezin, your mistake was to use
$
to expandpath
when printing. Unlikebash
ormake
,awk
doesn't use the$
to expand variables names to their value, but to refer to the fields of a line (similar toperl
).So just removing this will make your code work:
However, this is not really an
awk
ish solution: First of all, there is no need to initializepath
in aBEGIN
rule, non-defined variables default to""
or0
, depending on context.Also, any
awk
script consist of patterns and actions, the former stating when, the latter what to do. You have one action that's always executed (empty pattern), and internally uses (nested) conditionals to decide what to do.My solution would look like this:
And that's all. Removing all the comments, shortening the variable name and moving the
[O]FS
definitions to command line arguments, all you have to write is: