Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm running tests of a variable-size-and-contents test set. Data files are added and removed frequently. I'm looking for an automated way of gathering a file list.

All files are in subdirectories of D; I need the full directory and name added to a text file. However, I only need those files that have a "paired" file, which has the same filename but a different extension (so... different filename, but in a structured way). So, if there is a MyFileName.A and MyFileName.B, then I want D/.../MyFileName added to the file list.

There are .A files without .B files, but no .B files without .A files. If a .A has a .B file, then both files are in the same directory.

Any advice?

share|improve this question
ls D/*.B | sed 's/\.B$//' > file_list.txt? – mr_tron Jun 16 '14 at 11:55
up vote 4 down vote accepted

If none of the filenames contain any newlines, you can do:

find D -type f \( -name '*.A' -o -name '*.B' \) |
  sed 's/\.[^.]*$//' |
  sort |
  uniq -d >paired_files

This should work in the more general case where there are .B files without .A files.

To handle any filename using recent GNU tools:

find D -type f \( -name '*.A' -o -name '*.B' \) -print0 |
  sed -z 's/\.[^.]*$//' |
  sort -z |
  uniq -dz |
  tr '\0' '\n' >paired_files
share|improve this answer
Works perfectly, thanks! Flagged this as the answer as well as richard's, because this one generally applicable whereas richard's uses the very obvious property of if B then A – Gaminic Jun 16 '14 at 13:38

If you statement is true “there are no .B files without .A files.”, then get a list of .B files and remove the extension.

find $directory-to-search -name "*.B" | sed -r -e "s~(.*)\.B~\1~g"
share|improve this answer
Note that -r to enable extended expressions is not standardised. GNU sed uses it but OSX sed uses -E instead. Others may not implement extended expressions at all. – Graeme Jun 16 '14 at 12:13
I can't believe I didn't think of that. I guess that's why you should reexamine your assumptions when the problem changes. – Gaminic Jun 16 '14 at 13:34

With zsh:

print -rl mydir/**/*.A(.e_'REPLY=$REPLY:r; [[ -f $REPLY.B ]]'_)

:r removes the extension, so if the content of $REPLY was mydir/somedir/somefile.A after running REPLY=$REPLY:r its content becomes mydir/somedir/somefile;
the rest is similar to this answer.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.