2

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?

2 Answers2

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
muru
  • 197,895
  • 55
  • 485
  • 740
  • 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 03:27
2

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 5, 2020.

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.

2018-11-09 Filenames trunctated after first space.

2020-07-05 Speed up processing. Handle permission denied.

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

tmpLine=$(locate "$1")

Was anything found?

if [[ ${#tmpLine} -eq 0 ]] ; then echo "No files found. If files created today, did you run 'sudo updatedb' after?" exit 1 fi

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

Build output with columns separated by "|" for column command

tmpForm="ACCESS|OWNER|GROUP|SIZE|MODIFIED|NAME (updatdb last ran: $LastRun)"$'\n'

ThisYear=$(date +%Y)

while read -r Line; do

StatLine=$(stat --printf='%A|%U|%G|%s|%Y|%N\n' "$Line" | sed "s/'//g")

IFS="|" Arr=($StatLine)
Seconds="${Arr[4]}"
[[ $Seconds == "" ]] && continue    # Permission denied

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

StatLine="${StatLine/$Seconds/$HumanDate}"
tmpForm="$tmpForm$StatLine"$'\n'

done <<< "$tmpLine" # Read next locate line.

column -t -s '|' <<< "$tmpForm"

exit 0