Reputation: 21
Re-edited question as requested.
I have a QNAP NAS with a modified Debian OS. The shell is using GNU bash, version 3.2.57(1)-release (x86_64-QNAP-linux-gnu).
I have a program that analyses data and outputs it to a file in a three column format separated by a single space
12000 root 123456
5000 root rootpassword
300 administrator pa$$word
There are hundreds of lines in the file.
I want something to change that file so that the count will have thousand delimiters to be easy to read and be left padded out to 10 characters with spaces. It needs to run in CRON so it can be automated. Thus the above example will be
12,000 root 123456
5,000 root rootpassword
300 administrator pa$$word
I have written a bash script to extract the columns and perform the conversion then simply append the rest on. That works fine but with the delimiters and padding it is 30 lines long and the rest of the script, the main part, is only six. It looks horribly inefficient, takes a very long time and clumsy.
There must be a way to do this more efficiently with sed. Sed looks like it can do it or is there an alternative way with awk or another tool. Those tools are so complex that I have no idea how to do it.
Any ideas on a script that can be submitted via CRON to do this?
Upvotes: 0
Views: 81
Reputation: 103694
If you can use awk
it is fairly easy:
LC_ALL=en_US.UTF-8 awk '
{
s=$1
sub(/^[^ ]+ /,"",$0)
printf("%'"'"'d %s\n", s, $0)
}' your_file
With your example, prints:
12,345 02-01-2024 root reallylongpasswordthatissecure
9,999 01-01-2025 admin anotherreallylongpassword
300 01-01-2025 user 123456
You can also use GNU sed:
gsed -E ':a;s/^([0-9]+)([0-9]{3})\b/\1,\2/;ta' your_file
#same
You can also add a field width if desired to create a right justified column:
LC_ALL=en_US.UTF-8 awk '
{
s=$1
sub(/^[^ ]+ /,"",$0)
printf("%'"'"'10d %s\n", s, $0)
}' your_file
12,345 02-01-2024 root reallylongpasswordthatissecure
9,999 01-01-2025 admin anotherreallylongpassword
300 01-01-2025 user 123456
Upvotes: 3
Reputation: 33749
Assumptions:
One bash
idea using a while/read
loop and a printf
call:
while read -r fld1 rest_of_line
do
LC_ALL=en_US.UTF-8 printf "%'10d %s\n" "${fld1}" "${rest_of_line}"
done < file.txt
NOTES:
LC_ALL=en_US.UTF-8
depends on your default character seten_US.UTF-8
as neededThis generates:
12,345 02-01-2024 root reallylongpasswordthatissecure
9,999 01-01-2025 admin anotherreallylongpassword
300 01-01-2025 user 123456
Upvotes: 2