Reputation:
So I'm trying to read some config files and output the information from find piped into grep over to awk as follows:
find /path/to/file/ -name config.php -print0 | xargs -0 grep -E 'cfg_database|cfg_user|cfg_password' | awk -F"[:']" -v OFS="" '{print (NR%3==1) ? $1 " | Database: " : "", (NR%3==2) ? "Username: " : "", (NR%3==0) ? "Password: " : "", $5}'
There would be multiple results so by default, find | xargs grep output is:
/path/to/file/dir1/config.php:define('cfg_database', 'db1');
/path/to/file/dir1/config.php:define('cfg_user', 'user1');
/path/to/file/dir1/config.php:define('cfg_password', 'pass1');
/path/to/file/dir2/config.php:define('cfg_database', 'db2');
/path/to/file/dir2/config.php:define('cfg_user', 'user2');
/path/to/file/dir2/config.php:define('cfg_password', 'pass2');
With the command I have right now, the output is:
/path/to/file/dir1/config.php | Database: db1
Username: user1
Password: pass1
But I want to be able to prepend spaces so that all of the results are lined up based on the length of path to the file ($1) plus three more spaces.
/path/to/file/dir1/config.php | Database: db1
Username: user1
Password: pass1
The only methods I'm seeing here are using a loop within print for length($1), or using printf. I couldn't figure out any ways of getting the loop in the current command, and I don't know much about printf and couldn't figure out a way of determining what line is being read. Either way, would appreciate someone pointing me in the right direction.
Upvotes: 1
Views: 4550
Reputation: 37394
$ awk 'NR==1{s=length($1)+4}NR>1{$s=$1 OFS $2;$1=$2=""}1' file
or
$ awk '
NR==1 {
s=length($1)+4 # length of first field of first record + correction
}
NR>1 {
$s=$1 OFS $2 # use length to position to correct field
$1=$2="" # clean original fields
}1' file
/path/to/file/dir1/config.php | Database: db1
Username: user1
Password: pass1
Upvotes: 0
Reputation: 16997
your_command | awk 'FNR==1{l=index($0,"|")+1}FNR>1{$0=sprintf("%*s%s",l,"",$0)}1'
For example :
$ cat f
/path/to/file/dir1/config.php | Database: db1
Username: user1
Password: pass1
$ awk 'FNR==1{l=index($0,"|")+1}FNR>1{$0=sprintf("%*s%s",l,"",$0)}1' f
/path/to/file/dir1/config.php | Database: db1
Username: user1
Password: pass1
Explanation
index(str, sub)
It checks whether sub is a substring of str or not. On success, it returns the position where sub starts; otherwise it returns
0
. The first character of str is at position1
.
sprintf(format, expression1, …)
Return (without printing) the string that
printf
would have printed out with the same arguments
sprintf("%*s%s",l,"",$0)
Like C/C++ Specifies how much space to allocate for the string
*
The width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.
sprintf("%*s",5,"")
is same as
sprintf("%5s", "");
Example
Used to specify, in a dynamic way, what the width of the field is:
$ awk 'BEGIN{printf("%*s%s\n",5,"","mystring")}'
mystring
$ awk 'BEGIN{printf("%5s%s\n","","mystring")}'
mystring
Upvotes: 4
Reputation: 18351
awk 'NR==1{len=length($0)} {printf "%"len"s\n",$0}' yourfile
/path/to/file/dir1/config.php | Database: db1
Username: user1
Password: pass1
Here, the length of first line is used to calculate the format of the string output, its stored in len
variable.
Upvotes: 0