Search code examples
linuxawkcommand

AWK command for combining two files with separate ':' like output


Consider:

File 1

1
2
3

File 2

23
45
27
67
867

Output

1:23
1:45
1:27
1:67
1:867
2:23
2:45
2:27
2:67
2:867
3:23
3:45
3:27
3:67
3:867

How can I command this output using AWK using delimiter ':' from file 1 and file 2 like output?


Solution

  • There are many ways to solve your problem; this may suit your use-case:

    awk 'NR==FNR{a[++n]=$0; next} {for (i=1; i<=n; i++) {print $0 ":" a[i]}}' file2 file1
    1:23
    1:45
    1:27
    1:67
    1:867
    2:23
    2:45
    2:27
    2:67
    2:867
    3:23
    3:45
    3:27
    3:67
    3:867
    

    With nicer formatting and comments

    awk '
    NR==FNR{            # For the first file
           a[++n]=$0    # Load values into an array
           next         # Then skip to the next line/file
    }
    
    {
           for (i=1; i<=n; i++) {    # For all the items in the array
                  print $0 ":" a[i]  # Print the value from file1, then the value from the array
           }
    }' file2 file1
    1:23
    1:45
    1:27
    1:67
    1:867
    2:23
    2:45
    2:27
    2:67
    2:867
    3:23
    3:45
    3:27
    3:67
    3:867
    

    Or, perhaps with GNU parallel:

    parallel echo {1}":"{2} :::: file1 :::: file2
    1:23
    1:45
    1:27
    1:67
    1:867
    2:23
    2:45
    2:27
    2:67
    2:867
    3:23
    3:45
    3:27
    3:67
    3:867
    

    If you have <br/> characters in your input, you can delete anything that isn't a number using:

    awk 'NR==FNR{gsub("[^0-9]", "", $0); a[++n]=$0; next} {for (i=1; i<=n; i++) {gsub("[^0-9]", "", $0); print $0 ":" a[i]}}' file2 file1