1

Say I have the file data.log with the following contents:

[12/Mar/2015] /var/lib/file1.txt
[12/Mar/2015] /var/lib/file2.txt
[12/Mar/2015] /var/lib/file3.txt

How can I use awk and bash to store the contents of this file into an array where [12/Mar/2015] would be the element and /var/lib/fileN.txt its key?

McJohnson
  • 313
  • 1
  • 11

2 Answers2

4

bash:

# the data
$ cat data.log
[12/Mar/2015] /var/lib/file1.txt
[12/Mar/2015] /var/lib/file2.txt
[12/Mar/2015] /var/lib/file3.txt

# the associative array declaration
$ declare -A map

# read the data from the file into the array
$ while read -r date file; do map[$file]=$date; done < data.log

# iterate through the data
$ for key in "${!map[@]}"; do printf "%s => %s\n" "$key" "${map[$key]}"; done
/var/lib/file3.txt => [12/Mar/2015]
/var/lib/file2.txt => [12/Mar/2015]
/var/lib/file1.txt => [12/Mar/2015]
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • Yes, it works fine but I seem to be getting only this as output: `/var/lib/file2.txt => [12/Mar/2015] /var/lib/file1.txt => [12/Mar/2015]` without the last line – McJohnson Mar 08 '16 at 22:32
  • 2
    @McJohnson See http://stackoverflow.com/questions/15485555/read-last-line-of-file-in-bash-script-when-reading-file-line-by-line – Benjamin W. Mar 08 '16 at 22:34
  • Thank you both. @glenn jackman thank you for your time and answer. Accepted and upped. – McJohnson Mar 08 '16 at 22:38
2

In awk:

$ awk '{map[$2]=$1}END{for(key in map){printf "%s => %s\n",key,map[key]}}' infile
/var/lib/file2.txt => [12/Mar/2015]
/var/lib/file3.txt => [12/Mar/2015]
/var/lib/file1.txt => [12/Mar/2015]

Or, as a non-one-liner:

# For each line, use the second field as key and the first field as value
{
    map[$2] = $1
}

END {
    # Iterate over all keys
    for (key in map) {
        printf "%s => %s\n", key, map[key]
    }
}

This goes into a file, for example script.awk, and is then called with

awk -f script.awk infile
Benjamin W.
  • 46,058
  • 19
  • 106
  • 116