0

I'm trying to make a script that uses awk to get the recent file names from .config/okularrc and pipe them into dmenu, and back to awk to get the path for the name selected. However, I'm getting an error that tells me that there is a character that should be escaped in the regex.
Okularrc file:

[Recent Files]
File1[$e]=$HOME/documents/med/oh/OH Lecture (12)_Lead Poisoning Summary.pdf
File2[$e]=$HOME/ug/Biochemistry/1. biochemistry of kidney.pdf
File3[$e]=$HOME/ug/Archives/3. UG-(mid+final)-WAREED.pdf
File4[$e]=$HOME/ug/Biochemistry/1. b)iochemistry of kidney.pdf
Name1[$e]=OH Lecture (12)_Lead Poisoning Summary.pdf
Name2[$e]=1. biochemistry of kidney.pdf
Name3[$e]=3. UG-(mid+final)-WAREED.pdf
Name4[$e]=1. b)iochemistry of kidney.pdf

the script I made:

#!/bin/bash

DEBUG=1

# Get the names of the files
names=$(awk -F'=' '/^Name/{print $2} ' ~/.config/okularrc)
[ $DEBUG == 1 ] && echo -e "[*] Names are:\n$names\n"


# Pass the names to dmenu and select a file
selected_name=$(echo "$names" | dmenu -l 10 -i -p "Select a recent file:")
[ $DEBUG == 1 ] && echo -e "[*] Selected name is:\n$selected_name\n"

# Get the path of the selected file
file_path=$(awk -v name="$selected_name" -F'=' '$2 ~ name "$" && /^File/ {print $2}' ~/.config/okularrc)
[ $DEBUG == 1 ] && echo -e "[*] File path is:\n${file_path}\n"


# Run Okular with the path of the file
okular "${file_path/'$HOME'/$HOME}"

# If history is zero just start okular; TODO add browser
#[ -z $names ] && okular && exit 

and when i run this on files that have "(" it gives me this output:

[*] Names are:
1. b(iochemistry of kidney.pdf

[*] Selected name is:
1. b(iochemistry of kidney.pdf

awk: cmd. line:1: (FILENAME=/home/anonymous/.config/okularrc FNR=1) fatal: invalid regexp: Unmatched ( or \(: /1. b(iochemistry of kidney.pdf$/
[*] File path is:

I'm new to awk and i want to learn more, your help would be much appreciated

5
  • 3
    You could consider using the string-based index function instead of the regex-based ~ Commented May 21, 2023 at 20:46
  • Your other choice would be to escape all the regex special characters. Commented May 22, 2023 at 3:59
  • Thanks alot @steeldriver The index function solved it all, can i escape the regex chars inside a variable like i have here? Commented May 22, 2023 at 5:52
  • It would be possible to replace all / with \/, but that in itself would be hard to escape correctly (I would guess \\/). But for a generic regex that may contain any of ()[]{}?*+^$|, the only viable option might be to escape every character by prefixing with `\` (I think spurious escapes are ignored). Commented May 22, 2023 at 8:24
  • Given that the same info is yet in your tag "File" that you use anyway, why don't you pass the selected portion of that tag "File" to te selection tool ? The tag "Name" is superfluous because it contains information that is not sufficient to open the document anyway, and necessarily equal for the mapping to work ! Commented May 27, 2023 at 17:12

1 Answer 1

0

Replaced this line:

file_path=$(awk -v name="$selected_name" -F'=' '$2 ~ name "$" && /^File/ {print $2}' ~/.config/okularrc)

with this line:

file_path=$(awk -v name="$selected_name" -F'=' 'index($2,name) && /^File/ {print $2}' ~/.config/okularrc)

credits goes to @steeldriver

1
  • index($2,name) is not the string comparison equivalent of the regexp comparison $2 ~ name "$" as it'd say name foo matches $2 foobar, and your regexp comparison was already incomplete (didn't match at start of string). From your example, you just need $2 == name. Also, file names can contain = so you shouldn't be relying on using = as FS and selecting a field, $2, for this. There are other issues with your script too - ask a new question if you'd like help doing what you're trying to do robustly.
    – Ed Morton
    Commented May 22, 2023 at 11:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .