0

The locate command output is a little bland:

$ time locate etc/profile
/etc/profile
/etc/profile.d
/etc/profile.d/appmenu-qt5.sh
/etc/profile.d/apps-bin-path.sh
/etc/profile.d/bash_completion.sh
/etc/profile.d/cedilla-portuguese.sh
/etc/profile.d/jdk.csh
/etc/profile.d/jdk.sh
/etc/profile.d/vte-2.91.sh

real    0m0.696s
user    0m0.671s
sys     0m0.024s

How can I give more information to it like ll or ls -la does? Perhaps include headings too?

3

Using xargs and ls:

$ locate -0 etc/profile | xargs -0 ls -ld
-rw-r--r-- 1 root root  575 Oct 23  2015 /etc/profile
drwxr-xr-x 2 root root 4096 Apr 20 10:10 /etc/profile.d
-rw-r--r-- 1 root root   40 Nov 30  2015 /etc/profile.d/appmenu-qt5.sh
-rw-r--r-- 1 root root  663 May 18  2016 /etc/profile.d/bash_completion.sh
-rw-r--r-- 1 root root 1003 Dec 29  2015 /etc/profile.d/cedilla-portuguese.sh
-rwxr-xr-x 1 root root   31 Oct 18  2017 /etc/profile.d/go.sh
-rwxr-xr-x 1 root root  301 Feb 20  2013 /etc/profile.d/jdk.csh
-rwxr-xr-x 1 root root  299 Feb 20  2013 /etc/profile.d/jdk.sh
-rw-r--r-- 1 root root  999 Aug 23  2017 /etc/profile.d/libvirt-uri.sh
-rw-r--r-- 1 root root 1941 Mar 16  2016 /etc/profile.d/vte-2.91.sh
-rw-r--r-- 1 root root 1557 Apr 15  2016 /etc/profile.d/Z97-byobu.sh
  • That was my initial thinking but I had my old problems with xargs and tried to use {} placeholder. Plus I wanted to take out the link count and add heading with last sudo updatedb time. Still I have a hunch most of the world will like your one-liner better. Good job! – WinEunuuchs2Unix May 23 '18 at 3:27
0

I created a script called llocate for this purpose:

$ time llocate etc/profile
ACCESS      OWNER  GROUP  SIZE  MODIFIED      NAME (updatdb last ran: 2018-07-01 11:30:05)
-rw-r--r--  root   root   575   Nov 12  2017  /etc/profile
drwxr-xr-x  root   root   4096  Jun  4 17:19  /etc/profile.d
-rw-r--r--  root   root   40    Feb 16  2017  /etc/profile.d/appmenu-qt5.sh
-rw-r--r--  root   root   580   Oct 18  2017  /etc/profile.d/apps-bin-path.sh
-rw-r--r--  root   root   663   May 18  2016  /etc/profile.d/bash_completion.sh
-rw-r--r--  root   root   1003  Dec 29  2015  /etc/profile.d/cedilla-portuguese.sh
-rwxr-xr-x  root   root   301   Feb 20  2013  /etc/profile.d/jdk.csh
-rwxr-xr-x  root   root   299   Feb 20  2013  /etc/profile.d/jdk.sh
-rw-r--r--  root   root   1941  Mar 16  2016  /etc/profile.d/vte-2.91.sh

real    0m0.760s
user    0m0.754s
sys     0m0.020s

It takes .76 seconds to run versus .70 seconds for the regular locate command. The difference is negligible.


Bash script

The bash code is fairly straight forward. Copy the script below into the directory /home/YOUR_NAME/bin (you may have to create it first) or /usr/local/bin and mark it executable using:

chmod a+x /home/YOUR_NAME/bin/llocate`

Here's the script llocate:

#!/bin/bash

# NAME: llocate
# PATH: /mnt/e/bin
# DATE: May 22, 2018. Modified July 1, 2018.
# DESC: Use locate command but format output like `ll` with headings
# PARM: Parameter 1 = locate search string

# UPDT: 2018-07-01 Format date with Time or Previous Year like `ls -al`.

if [[ $# -eq 0 ]]; then
    echo "First parameter must be full or partial file names to search for."
    exit 1
fi

# Create unqique temporary file names
tmpLine=$(mktemp /tmp/llocate.XXXXX)
tmpForm=$(mktemp /tmp/llocate.XXXXX)

# Function Cleanup () Removes temporary files
CleanUp () {
    [[ -f $tmpLine ]] && rm -f $tmpLine     # Remove temporary files created
    [[ -f $tmpForm ]] && rm -f $tmpForm     #  at various program stages.
}

locate "$1" > $tmpLine

# Was anything found?
if [[ ! -s $tmpLine ]] ; then
    echo "No files found. If files created today, did you run 'sudo updatedb' after?"
    CleanUp
    exit 1
fi

LastRun=$(stat --printf=%y /var/lib/mlocate/mlocate.db | sed 's/\.[^\n]*//')

# Build output with columns separated by "|"
echo "ACCESS|OWNER|GROUP|SIZE|MODIFIED|NAME (updatdb last ran: $LastRun)" \
      > $tmpForm

while read -r Line; do

    StatLine=$(stat --printf='%A|%U|%G|%s|%Y|%N\n' "$Line" | sed 's/ [^|]*//' | \
               sed "s/'//g")
    IFS="|" Arr=($StatLine)
    Seconds="${Arr[4]}"

    # Format date with time if it's this year, else use file's year
    if [[ $(date -d @$Seconds +'%Y') == $(date +%Y) ]]; then
        HumanDate=$(date -d @$Seconds +'%b %_d %H:%M')
    else
        HumanDate=$(date -d @$Seconds +'%b %_d  %Y')
    fi

    StatLine="${StatLine/$Seconds/$HumanDate}"
    echo "$StatLine" >> $tmpForm

done < $tmpLine                             # Read next locate line.

cat $tmpForm | column -t -s '|'

CleanUp
exit 0

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.