Author

Alejandro Alcalde

Graduado en Ingeniería Informática en la ETSIIT, Granada.

More Alejandro Alcalde's posts

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)

When building regular expressions, I find useful to use some king of tool like regex texter, that allows to visualize the regular expression:

Créditos: inconfinder

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

Maybe this posts are also worth reading