I want to grep through a file of files, with path, for arbitrary patterns (given at runtime)
The problem is that I do NOT want to match those arbitrary patterns if they're in the "library path" portion of the line. But not all lines start with the library path.
I.E. given a file:
/other/more.mp3
/home/more/Music/more.mp3
/home/more/Music/Music.mp3
/home/more/Music/something other.mp3
/home/more/Music/other/something.mp3
and a "library" path of "/home/more/Music"
The pattern "Music" should match only line 3. The pattern "more" should match lines 1 and 2, but not 3. The pattern "other" should match lines 1,4, and 5.
Things I've tried:
^\($LIBRARY\)\ .*$PATTERN
^\($LIBRARY\).*$PATTERN
I could pre-process the file to remove $LIBRARY and re-add it after, probably by finding the matching line in the original file. But that seems a bit excessive, surely there's a simpler way?
CodePudding user response:
awk
is more suited for this job than grep
.
awk -v pat='more' -v lib='/home/more/Music' '{
s = $0; sub("^" lib, "", s)} s ~ pat' file
/other/more.mp3
/home/more/Music/more.mp3
# or else
awk -v pat='other' -v lib='/home/more/Music' '{
s = $0; sub("^" lib, "", s)} s ~ pat' file
/other/more.mp3
/home/more/Music/something other.mp3
/home/more/Music/other/something.mp3
# or else
awk -v pat='Music' -v lib='/home/more/Music' '{
s = $0; sub("^" lib, "", s)} s ~ pat' file
/home/more/Music/Music.mp3
Alternative gnu grep
solution:
lib='/home/more/Music'
# test 1
grep -ioP "^(?>$lib|).*more" file
/other/more
/home/more/Music/more
# test 2
grep -ioP "^(?>$lib|).*other" file
/other
/home/more/Music/something other
/home/more/Music/other
# test 3
grep -ioP "^(?>$lib|).*Music" file
/home/more/Music/Music
Note the use of atomic group in this regex, which is required to make sure we always match $lib
at the start when it is there.
CodePudding user response:
the most basic form of ERE
suffices -
___='/home/more/Music/'
for __ in Music more other; do
echo "\n :: $__ ::\n\n$(
echo '/other/more.mp3
/home/more/Music/more.mp3
/home/more/Music/Music.mp3
/home/more/Music/something other.mp3
/home/more/Music/other/something.mp3' |
{m,g,n}awk '$NF ~ __' FS="^$___" __="$__"
-- or --
{m,g,n}awk 'index($NF, __)' FS="^$___" __="$__"
)\n"
done | gcat -b
——
1 :: Music ::
2 /home/more/Music/Music.mp3
3 :: more ::
4 /other/more.mp3
5 /home/more/Music/more.mp3
6 :: other ::
7 /other/more.mp3
8 /home/more/Music/something other.mp3
9 /home/more/Music/other/something.mp3