Question: Haven't seen a solution similar enough to this yet...

I have two files each containing a list of file names. There are overlap in the contents of the files but file A contain some file names that are not in file B. Also, the file extensions are different in files A and B. That is:

```
A                     B
------------          --------------
file-1-2.txt          file-1-2.png
file-2-3.txt          file-3-4.png
file-3-4.txt
...

```

How do I combine the two files, comma-delimited, into one ignoring lines that don't match?

That is:

```
C
------------
file-1-2.txt,file-1-2.png
file-3-4.txt,file-3-4.png

```

I believe some usage of `awk` similar to the following will work:

```
awk 'FNR==NR{NOT SURE} {print $1,$2}' fileA fileB

```

Thanks in advance!

Answer: 
You could do:

```
$ awk 'function base(fn) {sub("[.][^.]*$", "", fn); return fn} 
       NR==FNR { fn[$1]; next} 
       {for (e in fn){ if (base(e)==base($1)){ printf "%s,%s\n", e, $1 }}} ' f1 f2
file-1-2.txt,file-1-2.png
file-3-4.txt,file-3-4.png

```

Since `awk` associative arrays are unordered, the order of the printout is determined by the order of the second file -- not the first. 

---

Explanation:

1. `function base(fn) {sub("[.][^.]*$", "", fn); return fn}` is a function that strips the extension from the filename (assuming that the extension is the non `.` characters to the right of the last `.` found. The entire name is returned if no `.` is found.)
2. `NR==FNR { fn[$1]; next}` read each line (each file name in this case) into an associative array. The `NR==FNR` is an `awk` idiom that is true only for the first file and `next` means the only this part is executed on the first file of file names. `$1` is used since the leading and trailing spaces are stripped. Since Unix filenames *can* have leading or trailing spaces, this is a rare ambiguity you need to resolve. If you don't want the lines stripped, you would use `$0` instead.
3. `{for (e in fn){ if (base(e)==base($1)){ printf "%s,%s\n", e, $1 }}}` now for any line other than from the first file (where `NR==FNR` is true since `next` skipped this part) loop through the saved file names. Print if the base name is the same.
Here's something fairly brute force:

```
file1="file1.txt"
file2="file2.txt"
out_file="out.txt"
touch $out_file
while read line ; do  # read the first file line by line
  file1_name="$(echo "$line" | cut -d'.' -f1)"    # get the filename without extension
  file2_name="$(grep "$file1_name\." $file2)"
  if [ -n "$file2_name" ]; then   #did we find a match
    echo "$line,$file2_name" >> $out_file
  else
    echo "Did not find a match to ${line} in $file2"
  fi
done < $file1 

```

We loop through file1 and look for matches in file 2. If found, we output to the output file. 

Other improvements: a better grep using regexp:

```
file2_name="$(grep -e "$file1_name\.[^.]*$" $file2)"

```

This looks for a line that starts with `$file1_name`, a dot `.` and then no more dots till the end which is the extension.