Skip to content
Advertisement

Using awk in a bash-script

I’ve been struggling to run an awk result as the arguments of a new awk command within a bash-script; something like this

    echo $(
        ag '^@' ~/dotfiles/shared/journal | 
        sed  's/(^.*.txt:)(.*)/2 | 1/g' | 
        fzf | 
        awk -F| 'BEGIN{OFS="";} { print ""/", substr($1, 3, length($1)-3), "/,/^~+$/","" ", substr($2, 1, length($2)-1) }' 
    ) | xargs -0 -I "{}" awk {}

To help eradicate (what I think is) inconsequential code to this problem,

    echo $(
        ag '^@' ~/dotfiles/shared/journal | 
        sed  's/(^.*.txt:)(.*)/2 | 1/g' | 
        fzf --height=40% --layout=reverse --info=inline --border --margin=1 | 
        awk -F| 'BEGIN{OFS="";} { print ""/", substr($1, 3, length($1)-3), "/,/^~+$/","" ", substr($2, 1, length($2)-1) }' 
)

gives me

"/@ Search Pattern/,/^~+$/" /home/sam/dotfiles/shared/journal/20210125.txt

and if prepend awk to this result, I get the answer I need. But I’m not able to make it work with xargs; it gives no output… Also, if I remove the xargs pipe, and substitue echo with awk, I get

awk: cmd. line:1: "/@
awk: cmd. line:1: ^ unterminated string

If I change the relevant quotation marks like so

awk -F| 'BEGIN{OFS="";} { print "47/", substr($1, 3, length($1)-3), "/,/^~+$/","47 ", substr($2, 1, length($2)-1) }'

I end up with this error

awk: cmd. line:1: '/@
awk: cmd. line:1: ^ invalid char ''' in expression

Is it even possible to create an awk command using the result of another awk-command?

EDIT: with more explanations Here’s an over-all picture of what I’m trying to do… I have a bunch of text files in my ~/dotfiles/shared/journal folder that have the following format

@ Project Title 

# Heading 1
some random text here, you know, typical markdown stuff

# Another Heading
Something **bold** here, etc., basically a typical markdown file

~~~
@ Another Project Title
# Second Project's Heading 
Some more markdown 

~~~

So the ag script goes through all the files, and lists out all the project titles (so conveniently prefixed with the @)

the sed line makes it all pretty to be piped into fzf, An average entry would look like this

2:@ Project Title | /home/sam/dotfiles/shared/journal/20210125.txt:

the awk line basically would take the output and reformat it so that it could be made into an argument, (looking like this)

'/@ Project Title/,/^~+$/' /home/sam/dotfiles/shared/journal/20210125.txt

So now, if I just take this result and prefix it with awk on my commandline like so

awk '/@ Project Title/,/^~+$/' /home/sam/dotfiles/shared/journal/20210125.txt

I would get

@ Project Title
# Heading 1
some random text here, you know, typical markdown stuff

# Another Heading
Something **bold** here, etc., basically a typical markdown file
~~~

But if I replace echo with awk, I get the errors mentioned above.

End of EDIT

** Side Note ** I would eventually want to pipe the markdown into weasyprint, but one thing at a time…

Advertisement

Answer

Your quoting is not really going to make it through xargs the way you would like. It’s not impossible to pull off, but I would instead do something like

ag '^@' ~/dotfiles/shared/journal | 
sed  's/(^.*.ejrnl:)(.*)/2 | 1/g' | 
fzf |
awk -F| 'BEGIN{OFS="";} { print "/", substr($1, 3, length($1)-3), "/,/^~+$/","" ", substr($2, 1, length($2)-1) }' 
| sh

However, this could still go wrong if you have several identical titles in your file. A more robust as well as simpler approach would extract the start and end line numbers while you are extracting the titles, and then just simply pass those through when you want to extract the whole journal entry. Something like (untested)

awk '/^@/ { if(prev) print pf ":" prev "," FNR-1 ":" ptitle;
    prev=FNR; pf=FILENAME; ptitle=$0; }
END { if (prev) print pf ":" prev "," FNR ":" ptitle }' ~/dotfiles/shared/journal/**/*.md |
fzf --height=40% --layout=reverse --info=inline --border --margin=1 | 
while IFS=: read -r file lines _; do
    sed -n "$lines"p "$file"
done
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement