Reputation: 358
Here is a original awk file ,i want to format it.
input content----original awk file named test.txt
awk 'BEGIN {maxlength = 0}\
{\
if (length($0) > maxlength) {\
maxlength = length($0);\
longest = $0;\
}\
}\
END {print longest}' somefile
expected output----well-formatted awk file
awk 'BEGIN {maxlength = 0} \
{ \
if (length($0) > maxlength) { \
maxlength = length($0); \
longest = $0; \
} \
} \
END {print longest}' somefile
step1:to get the longest line and chracters number
step1.awk
#! /usr/bin/awk
BEGIN {max =0 }
{
if (length($0) > max) { max = length($0)}
}
END {print max}
awk -f step1.awk test.txt
Now the max length for all lines is 50.
step2 to put \ in the position 50+2=52.
step2.awk
#! /usr/bin/awk
{
if($0 ~ /\\$/){
gsub(/\\$/,"",$0);
printf("%-*s\\\n",n,$0);
}
else{
printf("%s\n",$0);
}
}
awk -f step2.awk -v n=52 test.txt > well_formatted.txt
How to combine step1 and step2 into only one step,and combine step1.awk and step2.awk as one awk file?
Upvotes: 0
Views: 148
Reputation: 37404
Here is one for GNU awk. Two runs, first one finds the max length and the second one outputs. FS
is set to ""
so that each char goes on its field and the last char will in $NF
:
$ awk 'BEGIN{FS=OFS=""}NR==FNR{m=(m<NF?NF:m);next}$NF=="\\"{$NF=sprintf("% "m-NF+2"s",$NF)}1' file file
Output:
awk 'BEGIN {maxlength = 0} \
{ \
if (length($0) > maxlength) { \
maxlength = length($0); \
longest = $0; \
} \
} \
END {print longest}' somefile
Explained:
BEGIN { FS=OFS="" } # each char on different field
NR==FNR { m=(m<NF?NF:m); next } # find m ax length
$NF=="\\" { $NF=sprintf("% " m-NF+2 "s",$NF) } # NF gets space padded
1 # output
If you want the \
s further away from the code, change that 2
in sprintf
to suit your liking.
Upvotes: 1
Reputation: 16997
Better version, where you can use sub()
instead of gsub()
, and to avoid testing the same regexp twice sub(/\\$/,""){ ... }
awk 'FNR==NR{
if(length>max)max = length
next
}
sub(/\\$/,""){
printf "%-*s\\\n", max+2, $0
next
}1' test.txt test.txt
Explanation
awk 'FNR==NR{ # Here we read file and will find,
# max length of line in file
# FNR==NR is true when awk reads first file
if(length>max)max = length # find max length
next # stop processing go to next line
}
sub(/\\$/,""){ # Here we read same file once again,
# if substitution was made for the regex in record then
printf "%-*s\\\n", max+2, $0 # printf with format string max+2
next # go to next line
}1 # 1 at the end does default operation print $0,
# nothing but your else statement printf("%s\n",$0) in step2
' test.txt test.txt
You have not shown us, what's your input and expected output, with some assumption,
if your input looks like below
akshay@db-3325:/tmp$ cat f
123 \
\
12345
123456 \
1234567 \
123456789
12345
You get output as follows
akshay@db-3325:/tmp$ awk 'FNR==NR{ if(length>max)max = length; next}
sub(/\\$/,"",$0){ printf "%-*s\\\n",max+2,$0; next }1' f f
123 \
\
12345
123456 \
1234567 \
123456789
12345
Upvotes: 4
Reputation: 10039
awk '
# first round
FNR == NR {
# take longest (compare and take longest line by line)
M = M < (l = length( $0) ) ? l : M
# go to next line
next
}
# for every line of second round (due to previous next) that finish by /
/[/]$/ {
# if a modification is needed
if ( ( l = length( $0) ) < M ) {
# add the missing space (using sprintf "%9s" for 9 spaces)
sub( /[/]$/, sprintf( "%" (M - l) "s/", ""))
}
}
# print all line [modified or not] (7 is private joke but important is <> 0 )
7
' test.txt test.txt
Note:
Upvotes: 1
Reputation: 4937
Maybe something like this?
wc -L test.txt | cut -f1 -d' ' | xargs -I{} sed -i -e :a -e 's/^.\{1,'{}'\}$/& /;ta' test.txt && sed -i -r 's/(\\)([ ]*)$/\2\1/g' test.txt
Upvotes: 0