views:

120

answers:

6

How can I find the longest line in a .txt file and then fill all other lines at their end to that length with blank spaces?

My guess is this is easy to answer. I know very little about using the awk, paste command and such. Maybe someone can help me out. Thanks!

A little more specific... so far I can do the following. This would get the longest Line from a .txt File:

awk '{ if (length($0) > max) {max = length($0); maxline = $0} } END { print maxline }' in.txt

This fills the lines with blank spaces (till 50):

awk  'length <= 50 { printf "%-50s\n",$0 }' in.txt > out.txt

I just don't know to pass the value from one line to the other.

Why am I asking this? I want to merge two .txt files using the paste command. Text B will be positioned to the right of Text A. Lines in Text A will have different lengths. So if there are not enough blank spaces the layout isn't right.

+1  A: 

You can use wc to count the number of characters in a line. Measure all lines in the file to find the longest length. For all other files, (max length - line length) gives you the number of space characters to print at the end of the line (which you can do with printf).

Update: Is using awk a requirement? If not, try this:

# Measure the longest line in the file
maxlen=`wc -L filename.txt | cut -d ' ' -f 1`

# Pad each line to $maxlen characters
while read line
do
    printf "%-${maxlen}s\n" "$line" >> outfile.txt
done < filename.txt

Edit #2: If you don't have the -L option to wc, you can calculate the length of the longest line using the following loop:

maxlen=0
while read line
do
    thislen=`echo $line | wc -c`
    [ $[$thislen>$maxlen] ] && maxlen=$thislen
done < filename.txt

The ending value of $maxlen will be the length of the longest line.

bta
Yes, stumbled over that already also. Thanks. See above I tried to be more specific.
noexpert
Unfortunately that Option '-L' is not given in wc on mac os xAlso not 'wc --max-line-length'
noexpert
+1  A: 

wc -L or wc --max-line-length computes and displays the length of the longest line in the input (may not be available on all versions of wc).


With the max line length in some variable (say, $max), run

while read line
do
    printf "%-${max}s\n" $line
done < in.txt > out.txt
mobrule
Yes, stumbled over that already. Thanks. See above I tried to be more specific.
noexpert
+1  A: 

If 'shell scripting' can include Python scripts, something like this:

maxLen = 0
infile = open("file.txt", 'r')
outfile = open("out.txt", 'w')
for line in infile:
    if len(line)>maxLen: maxLen = len(line)
infile.seek(0)
for line in infile:
    rawline = line.strip('\r\n')
    out.write (rawline + ''.join([' ' for i in range(maxLen-len(rawline))]) + "\n")
infile.close ()
outfile.close ()

Fixing any off-by-one errors is left as an exercise for the reader! :-)

S..
Do you need a rewind operation between the two for loops?
Jonathan Leffler
Could you exploit the Python analogue of 'printf("%.80s\n", line)' to do the blank padding, where the 80 is the calculated maximum line length? You'd create the format string after the first pass through the file.
Jonathan Leffler
@Jon - yes, fixed :-) You could probably do something like the clever format string, it would be certainly be more concise!
S..
hopefully, I dont need python, that would be a whole new Area to me... :(
noexpert
`out.write('{0:{1}}\n'.format(rawline, maxLen))`
shambulator
+3  A: 

Usually I find that this type of question is a result of this thought process:

  1. I am trying to solve problem A
  2. I think doing process B will solve A
  3. I will ask how to achieve process B

You will get literal answers on how to achieve process B - but if you include the context of problem A, you will get better answers and probably one that solves problem A in a simpler manner than process B.

So, what problem are you trying to solve by making all the lines in a file the same length?

Ron Savage
Yes, sorry for not being specific enough. I want to merge 2 .txt Files with the 'paste' command. Text B will be positioned to the right of Text A. Lines in Text A will have different Lengths. So if there are not enough 'blank spaces' The Layout isn't right.
noexpert
How will the users view this file? If you make it a simple HTML file putting text from file A next to text from file B is as simple as wrapping the text in a single row table with two columns. No file processing involved at all.
Ron Savage
+1 for exposing the real problem.
Amardeep
+2  A: 

This is all you need:

pr  -W 80 -mtT file1 file2

Or, more verbosely:

pr --page-width=80 --merge --omit-header --omit-pagination file1 file2

Vary the number to change the layout of the result.

Dennis Williamson
+1 for finding the right tool for the *real* job.
Amardeep
Both Versions don't work. Thanks anyway.
noexpert
@noexpert: In what way do they not work? If you can be more specific I can be more helpful.
Dennis Williamson
A: 

here's how one way to it with just awk.

$ more file
jlsf
slf
asdfasfs
sd

$ awk 'FNR==NR{t=(length>=t)?length:t;next}length<t{for(o=1;o<=t-length;o++)s=s "|";$0=$0s;s=""}1' file file
jlsf||||
slf|||||
asdfasfs
sd||||||

Change "|" to spaces as desired.

ghostdog74
This is what I was Looking For. And it works like a Charm.Many Thanks to You and Everyone who took a little Time to help out.
noexpert