I would like to get some performance improvement suggestions to a simple project I made using Bash in Linux.

The target is to read all the `*.desktop` files, and extract `Name`, `Exec`, `Icon` and `Comment` entries. Then will be displayed in a GTK yad List.

I have built the code in two versions. Both versions works OK, but are very slow.

**Version 1 :** 

Read all the files one by one & `grep` the fields.
This version need about 9 seconds to read & `grep` 300 desktop files.

```
TimeStarted=$(date +%s.%N)
files=/usr/share/applications/*.desktop
fileindex=1 
for i in $(ls $files); do
  readarray -t executable < <(grep -m 1 "^Exec=" $i |cut -f 2 -d '=')
  readarray -t comment < <(grep -m 1 "^Comment=" $i |cut -f 2 -d '=')
  readarray -t comment2 < <(grep -m 1 "^GenericName=" $i |cut -f 2 -d '=')
  readarray -t mname < <(grep -m 1 "^Name=" $i |cut -f 2 -d '=')
  readarray -t icon < <(grep -m 1 "^Icon=" $i |cut -f 2 -d '=')
  if [[ $comment = "" ]]; then
     comment=$comment2
  fi
  yadlist+=( "$fileindex" "${icon[0]}" "${mname[0]}" "$i" "${executable[0]}" "${comment[0]}" ) #this sets double quotes in each variable.
  fileindex=$(($fileindex+1))
done
TimeFinished=$(date +%s.%N); TimeDiff=$(echo "$TimeFinished - $TimeStarted" | bc -l)

```

**Version 2:**

`grep` all the files at once for required fields.
This version improves the performance of the script, and needs 2 seconds to `grep` 300 desktop files.

```
TimeStarted=$(date +%s.%N)
files=/usr/share/applications/*.desktop
i=$files 
fileindex=1
IFS=$'\n'
readarray -t fi < <(printf '%s\n' $i)
readarray -t executable < <(grep  -m 1 '^Exec=' $i)
readarray -t noexecutable < <(grep  -L '^Exec=' $i)
readarray -t comment < <(grep -m 1 "^Comment=" $i )
readarray -t nocomment < <(grep -L "^Comment=" $i ) 
readarray -t comment2 < <(grep -m 1 "^GenericName=" $i )
readarray -t nocomment2 < <(grep -L "^GenericName=" $i )
readarray -t mname < <(grep -m 1 "^Name=" $i )
readarray -t nomname < <(grep -L "^Name=" $i )  
readarray -t icon < <(grep -m 1 "^Icon=" $i )
readarray -t noicon < <(grep -L "^Icon=" $i )   

for items1 in ${noexecutable[@]}; do
    executable+=($(echo "$items1"":Exec=None"))
done

for items2 in ${nocomment[@]}; do
    comment+=($(echo "$items2"":Comment=None"))
done
for items3 in ${nocomment2[@]}; do
    comment2+=($(echo "$items3"":GenericName=None"))
done

for items4 in ${nomname[@]}; do
    mname+=($(echo "$items4"":Name=None"))
done

for items5 in ${noicon[@]}; do
    icon+=($(echo "$items5"":Icon=None"))
done

sortexecutable=($(sort <<<"${executable[*]}"))
sortcomment=($(sort <<<"${comment[*]}"))
sortcomment2=($(sort <<<"${comment2[*]}"))
sortmname=($(sort <<<"${mname[*]}"))
sorticon=($(sort <<<"${icon[*]}"))

trimexecutable=($(grep  -Po '(?<=Exec=)[ --0-9A-Za-z/]*' <<<"${sortexecutable[*]}"))
trimcomment=($(grep -Po '(?<=Comment=)[ --0-9A-Za-z/]*' <<<"${sortcomment[*]}"))
trimcomment2=($(grep -Po '(?<=GenericName=)[ --0-9A-Za-z/]*' <<<"${sortcomment2[*]}"))
trimmname=($(grep -Po '(?<=Name=)[ --0-9A-Za-z/]*' <<<"${sortmname[*]}"))
trimicon=($(grep -Po '(?<=Icon=)[ --0-9A-Za-z/]*' <<<"${sorticon[*]}"))

unset IFS

ae=0
for aeitem in ${fi[@]};do
    if [[ ${trimcomment[ae]} = "None" ]]; then
        trimcomment[ae]=${trimcomment2[ae]}
    fi
    yadlist+=( "$fileindex" "${trimicon[$ae]}" "${trimmname[$ae]}" "${fi[$ae]}" "${trimexecutable[$ae]}" "${trimcomment[$ae]}" ) #this sets double quotes in each variable.
    fileindex=$(($fileindex+1))
    ae=$(($ae+1))
done
TimeFinished=$(date +%s.%N); TimeDiff=$(echo "$TimeFinished - $TimeStarted" | bc -l)

```

Remarks:

a) Some `.dekstop` files do not include all the required fields.

b) Performance refers to 64-bit Intel Celeron N3050 - 4GB ram machine, running 64bit Debian 8 Sid with XFCE and GNU bash 4.4.0(1) and GNU `grep` 2.26. PS: Performance of 9 or 2 seconds is also verified by `time ./script.sh`. 

c) The version 2 script performance can achieve below 0.5 seconds if I remove the "for" sections, but then yadlist becomes a chaos due to the missing fields in some `.desktop` files.

**Result:**

According to my opinion, even 2 seconds to `grep` 300 files it is still too much time for such a small number of files. 

Is it possible to further optimize this scripts performance in Bash?

As a sample , you can have a look at this `caja.desktop` file, taken from my system. Notice that `Comment` entry is missing. 

```
[Desktop Entry]
Name=Caja
Name[af]=Caja
<More Name entries for different locale>
GenericName=File Manager
GenericName[af]=Lêerbestuurder
<more GenericName entries for different locale>
Exec=caja
Icon=system-file-manager
Terminal=false
Type=Application
StartupNotify=true
NoDisplay=true
OnlyShowIn=MATE;

```

In other `.desktop` files, the comment entry (if present) looks like this:

```
Comment=View multi-page documents
<various Comment entries for different locale>

```