2

What I am trying to do is kind of hard to explain. Let's say I have a directory with a bunch of different users submitting stuff into it. I ask for a file with the extension ".foo" from everyone. Then I asked for a file with the extension ".bar" from everyone. I want a list of names of everyone who submitted .foo, but did not submit .bar.

I'm assuming you somehow use grep twice and include the owner name inside the grep, but that's kind of where I get confused. I am trying to do this all in one command pipeline.

This is what I'm trying to do to retrieve the names:

find . -type f -printf "%u %f\n" | grep '%u .foo' | grep -v '%u .bar'

My two problems here are that %u doesn't give the name from the printf and that the excluding bar part isn't dependent off of grep foo. It's meant to list the names of all of the people that own foo, then remove the names of the people who have submitted bar.

Structure as per request:

|--myDirectory
   ├── samantha.foo - (owner: samantha warren)
   ├── samantha.bar - (owner: samantha warren
   ├── robert.foo   - (owner: robert jones)
   ├── doug.foo     - (owner: doug field)
   ├── doug.bar     - (owner: doug field)
   ├── emily.foo    - (owner: emily smith)

The output should be as follows:

robert jones
emily smith
qiterpot
  • 37
  • 5
  • 3
    How can multiple users "submit" the same file name in the same directory? Each would overwrite the previous. – kaylum Feb 20 '17 at 00:17
  • 1
    Don't make us guess about the specifics of your problem,. See http://stackoverflow.com/questions/39338196/extract-zip-file-generated-in-windows-using-python-2-7-and-zipfile-in-linux (allowing for zipfiles VS in-place dir/files) as an excellent example of specifying a Q related to dirs/sub-dirs/files. Edit your Q to include example files/dirs that should be processes as well as those that shouldn't be processed, then include your required result. Good luck. – shellter Feb 20 '17 at 00:55
  • 1
    Good show! Glad you got an answer. Good luck. – shellter Feb 22 '17 at 17:20

1 Answers1

2

It doesn't look like samantha.foo is owned by samantha in the sense of Linux file ownership. The ownership here seems to be within your application. If your filenames contain the owner name, you can try something like:

# Get all files with extensions foo and bar
foos=(*.foo)
bars=(*.bar)
# Strip the extensions to get the usernames
users_with_foo=("${foos[@]%.foo}")
users_with_bar=("${bars[@]%.bar}")
# Filter the usernames.
grep -vxf <(printf "%s\n" "${users_with_bar[@]}") <(printf "%s\n" "${users_with_foo[@]}")

With grep, -v prints lines that don't match any patterns, -x looks for exact matches (the whole line must match the pattern) and -f is used to read patterns from an input file. Here, the "files" are from process substitution (<(...)). So the printf commands' output are provided as files to grep, which it uses as files for patterns and input.

muru
  • 4,723
  • 1
  • 34
  • 78
  • Thanks, I had to adjust it a bit to put it into one command pipeline, but it definitely got me the right answer. Can you explain how the filter process of the printf's works? – qiterpot Feb 21 '17 at 01:58