Table Of Contents
In GNU/Linux, locate
command is useful to find files in the file system by querying a database. Here is how to use with regular expressions.” Its man
description is:
locate reads one or more databases prepared by updatedb(8) and writes file names matching at least one of the PATTERNs to standard output, one per line.
This post arises from a problem I had some days ago. I have a file with some of my Favorite songs. I update this file on a regular basis and I wanted to generate a playlist from that file. The solution was to write a script which loop through all items in the file and search where the each file is located in the hard drive.
UPDATE: Some time ago I improved this idea and wrote a
Python
script to create music playlists with a given length.
Regular expressions in Locate
Locate accepts complex regexs, in order to enable them, give locate
-regex
option.
Basically the problem is as follows: Given a text file with filenames, get the absolute path for each file in the textfile. For example, a file name “Author - Song Name” will be stored in the file as “Song Name”.
Writing the regular expression
Here is the regex
needed:
$i.*(\.mp4|\.mp3)
$i
stores the song name..*
match zero or more characters after the song name.(\.mp4|\.mp3)
match only files with mp3 or mp4 extensions.
When building regular expressions, I find useful to use some king of tool like regex tester, that allows to visualize the regular expression:
Script
Once the regular expression is finished, the script that process the file with the song names and creates a playlist is as follows:
#!/bin/bash
names=`cat TEXT_FILE_WITH_SONG_NAMES`
IFS='
'
> /path/to/playlist.m3u
for i in $nombres
do
echo "locate --regex -i \"$i.*(\.mp4|\.mp3)\""
locate --regex -i "$i.*(\.mp4|\.mp3)" | tee -a /path/to/playlist.m3u
done
IFS=' '
IFS
is set to line break, because for
by default would consider the space as a separator, instead of a new line.
As an alternative, suggested by @ingenieríainv is to use while read $i
:
#!/bin/bash
names=`cat ARCHIVO_CON_LISTA_DE_NOMBRES`
> /path/to/playlist.m3u
cat $nombres | while read i
do
echo "locate --regex -i \"$i.*(\.mp4|\.mp3)\""
locate --regex -i "$i.*(\.mp4|\.mp3)" | tee -a /path/to/playlist.m3u
done
And so IFS
is no longer needed.
Tools
- RegEx Tester »» regexpal.com
Spot a typo?: Help me fix it by contacting me or commenting below!