简体   繁体   中英

Bash grep variable from multiple variables on a single line

I am using GNU bash, version 4.2.20(1)-release (x86_64-pc-linux-gnu). I have a music file list I dumped into a variable: $pltemp .

Example:

/Music/New/2010s/2011;Ziggy Marley;Reggae In My Head

I wish to grep the 3rd field above, in the Master-Music-List.txt, then continue another grep for the 2nd field. If both matched, print else echo "Not Matched".

So the above will search for the Song Title (Reggae In My Head), then will make sure it has the artist "Shaggy" on the same line, for a success.

So far, success for a non-variable grep;

$ grep -i -w -E 'shaggy.*angel' Master-Music-MM-Playlist.m3u
$ if ! grep Shaggy Master-Music-MM-Playlist.m3u ; then echo "Not Found"; fi
$ grep -i -w Angel Master-Music-MM-Playlist.m3u | grep -i -w shaggy

I'm not sure how to best construct the 'entire' list to process.

  • I want to do this on a single line.

I used this to dump the list into the variable $pltemp ...

Original: \\Music\\New\\2010s\\2011\\Ziggy Marley - Reggae In My Head.mp3

$ pltemp="$(cat Reggae.m3u | sed -e 's/\(.*\)\\/\1;/' -e 's/\(.*\)\ -\ /\1;/' -e 's/\\/\//g' -e 's/\\/\//g' -e 's/.mp3//')"

If you realy want to "grep this, then grep that", you need something more complex than grep by itself. How about awk ?

awk -F';' '$3~/title/ && $2~/artist/ {print;n=1;exit;} END {if(n=0)print "Not matched";}'

If you want to make this search accessible as a script, the same thing simply changes form. For example:

#!/bin/sh

awk -F';' -vartist="$1" -vtitle="$2" '$3~title && $2~artist {print;n=1;exit;} END {if(n=0)print "Not matched";}'

Write this to a file, make it executable, and pipe stuff to it, with the artist substring/regex you're looking for as the first command line option, and the title substring/regex as the second.

On the other hand, what you're looking for might just be a slightly more complex regular expression. Let's wrap it in bash for you:

if ! echo "$pltemp" | egrep '^[^;]+;[^;]*artist[^;]*;.*title'; then
  echo "Not matched"
fi

You can compress this to a single line if you like. Or make it a stand-along shell script, or make it a function in your .bashrc file.

awk -F ';' -v title="$title" -v artist="$artist" '$3 ~ title && $2 ~ artist'

Well, none of the above worked, so I came up with this...

for i in *.m3u; do 
    cat "$i" | sed 's/.*\\//' | while read z; do 
        grep --color=never -i -w -m 1 "$z" Master-Music-Playlist.m3u \
        | echo "#NotFound;"$z" "
        done  > "$i"-MM-Final.txt;
done

Each line is read ( \\Music\\Lady Gaga - Paparazzi.mp3 ), the path is stripped, the song is searched in the Master Music List, if not found, it echos "Not Found" , saved into a new playlist.

Works {Solved}

Thanks anyway.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM