You are not logged in.

#1 2023-04-12 06:09:00

rifaz_n
Member
From: Bangladesh
Registered: 2021-09-20
Posts: 16

Suggest adding whitespace to this awk program

Hi guys

To make the following awk invocation more readable, I'm looking for some wisdom in adding some whitespace:

EXPENSE_ACCOUNTS="$(awk '/open Expenses/ { gsub("Expenses:", "", $3); print $3; }' "$FILE" | tr '\n' ',')"

I have tried:

EXPENSE_ACCOUNTS="$(awk \
  '/open Expenses/ {
    gsub("Expenses:", "", $3); print $3;
  }' "$FILE" | tr '\n' ',')"

But wondering if it can be made better.

Breaking down the code:

  1. Only operate on lines that have "open Expenses"

  2. Use gsub to edit 3rd column by removing "Expenses:"

  3. Print the updated 3rd column

  4. tr makes all newlines into comma separated single line

Sample input:

2023-03-22 open Expenses:Misc    BDT
2023-03-22 open Expenses:Food              BDT
2023-03-22 open Equity:Opening-Balances
2023-03-22 open Assets:Cash
2023-03-22 open Assets:SomeAccount
2023-03-22 open Income:Salary

2023-03-22 * "Opening Balance"
	Assets:Cash                                          5  BDT
	Equity:Opening-Balances                 -5  BDT

Sample Output

Misc,Food,

Much appreciated! Thanks!

Last edited by rifaz_n (2023-04-12 06:40:33)

Offline

#2 2023-04-12 07:50:53

duyinthee
Member
Registered: 2015-06-14
Posts: 228
Website

Re: Suggest adding whitespace to this awk program

cat simpleinputfile | awk -F '[: ]' '/open Expenses/ {print $4}' | tr '\n' ","

Offline

#3 2023-04-12 08:23:44

Raynman
Member
Registered: 2011-10-22
Posts: 1,539

Re: Suggest adding whitespace to this awk program

Instead of tr, you could use

awk -v ORS=,

For the rest it depends on how much the input can vary and how robust you want it to be. Matching /open Expenses:/ seems like a shortcut to say that $2 should equal "open" and $3 should start with "Expenses:". duyinthee came up with another shortcut. But short isn't necessarily more readable and shortcuts may end up causing unintended matches; sometimes it's better to explicitly say what you mean, especially in a script (rather than a one-time command you run in an interactive shell).

Last edited by Raynman (2023-04-12 08:30:31)

Offline

#4 2023-04-12 11:36:25

rifaz_n
Member
From: Bangladesh
Registered: 2021-09-20
Posts: 16

Re: Suggest adding whitespace to this awk program

Raynman wrote:

Instead of tr, you could use

awk -v ORS=,

This is certainly excellent. Thanks!

duyinthee wrote:
cat simpleinputfile | awk -F '[: ]' '/open Expenses/ {print $4}' | tr '\n' ","

This certainly works, and is more succinct than what I did, but there will be lines having patterns like

Expenses:Food:RestaurantName

and more generally

Expenses:Place:Purpose

and in these cases I want the Places:Purpose parts. The separation by : (colons) can go for deeper levels and I just want to trim the Expenses: part.

Also, is there a way I can get inline code block in BB code?

Offline

#5 2023-04-12 13:16:53

seth
Member
Registered: 2012-09-03
Posts: 60,000

Re: Suggest adding whitespace to this awk program

For embeddign awk scripts into bash see eg. https://stackoverflow.com/questions/648 … ash-script
bbcode doesn't support inline codes, unfortunately.
I pondered about turning "ins" or "em" into such, but that relies on a userstyle and doesn't really translate for everyone else.

Offline

#6 2023-04-12 13:47:53

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,330
Website

Re: Suggest adding whitespace to this awk program

I don't have much to say on the formating (just aim for consistency with the rest of the script that this is in), but you can get rid of the call to tr:

EXPENSE_ACCOUNTS=$(awk '
   /open Expenses/ {
      a=a","$3
   }
   END {
      gsub("Expenses:", "", a)
      print substr(a,2)
   }' $FILE)

You could also do this without awk (feel free to give the variables better names):

while read a b c d; do
   case $b$c in openExpenses:*)
      printf ',%s' ${c#Expenses:}
   esac
done < $FILE | cut -c2-

Or if you prefer:

while read a b c d; do
   case $b$c in openExpenses:*) ;; *) continue ;; esac
   printf ',%s' ${c#Expenses:}
done < input | cut -c2-

If you don't mind the trailing comma on the final output (which was present in your original example) you could switch the printf format string to '%s,' and drop the pipe through cut.

Last edited by Trilby (2023-04-12 23:30:48)


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

Board footer

Powered by FluxBB