You are not logged in.
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:
Only operate on lines that have "open Expenses"
Use gsub to edit 3rd column by removing "Expenses:"
Print the updated 3rd column
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
cat simpleinputfile | awk -F '[: ]' '/open Expenses/ {print $4}' | tr '\n' ","
Offline
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
Instead of tr, you could use
awk -v ORS=,
This is certainly excellent. Thanks!
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
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
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