Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

This is my file,

TLRUIDA CBdms    Status            DP  6/1/1         DC  6/1/5         0 Y
TLRUIDA CBdms    Status            DP  6/2/1         DC  6/2/5         0 Y
TLRUIDA CBdms    Status            DP  6/3/1         DC  6/3/5         0 Y
TLRUIDA CBdms    Status            DP  6/4/1         DC  6/4/5         0 Y
TLRUIDA CBdms    Status            DP  6/5/1         DC  6/5/5         0 Y
TLRUIDA CBdms    Status            DP  6/6/1         DC  6/6/5         0 Y
TLRUIDA CBdms    Status            DP  6/7/1         DC  6/7/5         0 Y
TLRUIDA CBdms    Status            DP  6/8/1         DC  6/8/5         0 Y
TLRUIDA CBdms    Status            DP  6/9/1         DC  6/9/5         0 Y
TLRUIDA CBdms    Status            DP  6/10/1         DC  6/10/5         0 Y
TLRUIDA CBdms    Status            DP  6/11/1         DC  6/11/5         0 Y
TLRUIDA CBdms    Status            DP  6/12/1         DC  6/12/5         0 Y    

I have alignment problem from the row after digit 10 is started. And I want the format below mentioned,

TLRUIDA CBdms    Status            DP  6/1/1         DC  6/1/5         0 Y
TLRUIDA CBdms    Status            DP  6/2/1         DC  6/2/5         0 Y
TLRUIDA CBdms    Status            DP  6/3/1         DC  6/3/5         0 Y
TLRUIDA CBdms    Status            DP  6/4/1         DC  6/4/5         0 Y
TLRUIDA CBdms    Status            DP  6/5/1         DC  6/5/5         0 Y
TLRUIDA CBdms    Status            DP  6/6/1         DC  6/6/5         0 Y
TLRUIDA CBdms    Status            DP  6/7/1         DC  6/7/5         0 Y
TLRUIDA CBdms    Status            DP  6/8/1         DC  6/8/5         0 Y
TLRUIDA CBdms    Status            DP  6/9/1         DC  6/9/5         0 Y
TLRUIDA CBdms    Status            DP  6/10/1        DC  6/10/5        0 Y
TLRUIDA CBdms    Status            DP  6/11/1        DC  6/11/5        0 Y
TLRUIDA CBdms    Status            DP  6/12/1        DC  6/12/5        0 Y
share|improve this question
up vote 2 down vote accepted

This sed command fixes the given output:

sed 's=\(D[CP] *./../.\) =\1=g'

It removes one space after the ./../. after DC and DP. If the other numbers can get longer, too, sed is probably not the right tool for the job.

share|improve this answer
    
yes it is working fine.... thanks @choroba – pmaipmui Jan 21 at 9:35

The right tool for this job is column. You can specify column separator with -o (on OS X it's -s) , e.g.:

column -t -o '   ' file

gives

TLRUIDA   CBdms   Status   DP   6/1/1    DC   6/1/5    0   Y
TLRUIDA   CBdms   Status   DP   6/2/1    DC   6/2/5    0   Y
TLRUIDA   CBdms   Status   DP   6/3/1    DC   6/3/5    0   Y
TLRUIDA   CBdms   Status   DP   6/4/1    DC   6/4/5    0   Y
TLRUIDA   CBdms   Status   DP   6/5/1    DC   6/5/5    0   Y
TLRUIDA   CBdms   Status   DP   6/6/1    DC   6/6/5    0   Y
TLRUIDA   CBdms   Status   DP   6/7/1    DC   6/7/5    0   Y
TLRUIDA   CBdms   Status   DP   6/8/1    DC   6/8/5    0   Y
TLRUIDA   CBdms   Status   DP   6/9/1    DC   6/9/5    0   Y
TLRUIDA   CBdms   Status   DP   6/10/1   DC   6/10/5   0   Y
TLRUIDA   CBdms   Status   DP   6/11/1   DC   6/11/5   0   Y
TLRUIDA   CBdms   Status   DP   6/12/1   DC   6/12/5   0   Y
share|improve this answer
    
I am using solaris 10.... column is not working – pmaipmui Jan 21 at 9:22
    
@pmaipmui Thats a pitty. – jimmij Jan 21 at 9:24
3  
I am undeleting this since the next person to find the question might not be on a Solaris machine and this would be useful for them. – terdon Jan 21 at 10:10

In this particular case, it will be enough to just change all occurrences of two or more spaces to a tab:

sed 's/  */\t/g' file

For a more general solution, you can make sure each column is printed with the right width using printf. You can do this directly in the shell:

$ while read line; do 
    printf '%-8s%-6s%-7s%-3s%-8s%-3s%-7s%-2s%-2s\n' $line; 
done < file
TLRUIDA CBdms Status DP 6/1/1   DC 6/1/5  0 Y 
TLRUIDA CBdms Status DP 6/2/1   DC 6/2/5  0 Y 
TLRUIDA CBdms Status DP 6/3/1   DC 6/3/5  0 Y 
TLRUIDA CBdms Status DP 6/4/1   DC 6/4/5  0 Y 
TLRUIDA CBdms Status DP 6/5/1   DC 6/5/5  0 Y 
TLRUIDA CBdms Status DP 6/6/1   DC 6/6/5  0 Y 
TLRUIDA CBdms Status DP 6/7/1   DC 6/7/5  0 Y 
TLRUIDA CBdms Status DP 6/8/1   DC 6/8/5  0 Y 
TLRUIDA CBdms Status DP 6/9/1   DC 6/9/5  0 Y 
TLRUIDA CBdms Status DP 6/10/1  DC 6/10/5 0 Y 
TLRUIDA CBdms Status DP 6/11/1  DC 6/11/5 0 Y 
TLRUIDA CBdms Status DP 6/12/1  DC 6/12/5 0 Y 

Or, more safely for arbitrary input:

$ while read a b c d e f g h i; do 
    printf '%-8s%-6s%-7s%-3s%-8s%-3s%-7s%-2s%-2s\n' "$a" "$b" "$c" "$d" "$e" "$f" "$g" "$h" "$i"; 
done < file
TLRUIDA CBdms Status DP 6/1/1   DC 6/1/5  0 Y 
TLRUIDA CBdms Status DP 6/2/1   DC 6/2/5  0 Y 
TLRUIDA CBdms Status DP 6/3/1   DC 6/3/5  0 Y 
TLRUIDA CBdms Status DP 6/4/1   DC 6/4/5  0 Y 
TLRUIDA CBdms Status DP 6/5/1   DC 6/5/5  0 Y 
TLRUIDA CBdms Status DP 6/6/1   DC 6/6/5  0 Y 
TLRUIDA CBdms Status DP 6/7/1   DC 6/7/5  0 Y 
TLRUIDA CBdms Status DP 6/8/1   DC 6/8/5  0 Y 
TLRUIDA CBdms Status DP 6/9/1   DC 6/9/5  0 Y 
TLRUIDA CBdms Status DP 6/10/1  DC 6/10/5 0 Y 
TLRUIDA CBdms Status DP 6/11/1  DC 6/11/5 0 Y 
TLRUIDA CBdms Status DP 6/12/1  DC 6/12/5 0 Y 

You could do it more quickly and succinctly using something like perl:

$ perl -lane 'printf "%-8s%-6s%-7s%-3s%-8s%-3s%-7s%-2s%-2s\n",@F' file
TLRUIDA CBdms Status DP 6/1/1   DC 6/1/5  0 Y 
TLRUIDA CBdms Status DP 6/2/1   DC 6/2/5  0 Y 
TLRUIDA CBdms Status DP 6/3/1   DC 6/3/5  0 Y 
TLRUIDA CBdms Status DP 6/4/1   DC 6/4/5  0 Y 
TLRUIDA CBdms Status DP 6/5/1   DC 6/5/5  0 Y 
TLRUIDA CBdms Status DP 6/6/1   DC 6/6/5  0 Y 
TLRUIDA CBdms Status DP 6/7/1   DC 6/7/5  0 Y 
TLRUIDA CBdms Status DP 6/8/1   DC 6/8/5  0 Y 
TLRUIDA CBdms Status DP 6/9/1   DC 6/9/5  0 Y 
TLRUIDA CBdms Status DP 6/10/1  DC 6/10/5 0 Y 
TLRUIDA CBdms Status DP 6/11/1  DC 6/11/5 0 Y 
TLRUIDA CBdms Status DP 6/12/1  DC 6/12/5 0 Y 

The benefit of using printf is that you can specify a minimum column width for each column. The means that if one of your columns can have a much longer value, it will still work. For example, if the first field of one of your lines could be averylongfieldindeed, you could set the minimum width of the 1st column to 21 and have aligned output:

$ perl -lane 'printf "%-21s%-6s%-7s%-3s%-8s%-3s%-7s%-2s%-2s\n",@F' file
averylongfieldindeed CBdms Status DP 6/1/1   DC 6/1/5  0 Y 
TLRUIDA              CBdms Status DP 6/2/1   DC 6/2/5  0 Y 
TLRUIDA              CBdms Status DP 6/3/1   DC 6/3/5  0 Y 
TLRUIDA              CBdms Status DP 6/4/1   DC 6/4/5  0 Y 
TLRUIDA              CBdms Status DP 6/5/1   DC 6/5/5  0 Y 
TLRUIDA              CBdms Status DP 6/6/1   DC 6/6/5  0 Y 
TLRUIDA              CBdms Status DP 6/7/1   DC 6/7/5  0 Y 
TLRUIDA              CBdms Status DP 6/8/1   DC 6/8/5  0 Y 
TLRUIDA              CBdms Status DP 6/9/1   DC 6/9/5  0 Y 
TLRUIDA              CBdms Status DP 6/10/1  DC 6/10/5 0 Y 
TLRUIDA              CBdms Status DP 6/11/1  DC 6/11/5 0 Y 
TLRUIDA              CBdms Status DP 6/12/1  DC 6/12/5 0 Y 

By contrast, using tabs wouldn't work:

$ sed  -e "s/\s\+/\t/g" file
averylongfieldindeed    CBdms   Status  DP  6/1/1   DC  6/1/5   0   Y
TLRUIDA CBdms   Status  DP  6/2/1   DC  6/2/5   0   Y
TLRUIDA CBdms   Status  DP  6/3/1   DC  6/3/5   0   Y
TLRUIDA CBdms   Status  DP  6/4/1   DC  6/4/5   0   Y
TLRUIDA CBdms   Status  DP  6/5/1   DC  6/5/5   0   Y
TLRUIDA CBdms   Status  DP  6/6/1   DC  6/6/5   0   Y
TLRUIDA CBdms   Status  DP  6/7/1   DC  6/7/5   0   Y
TLRUIDA CBdms   Status  DP  6/8/1   DC  6/8/5   0   Y
TLRUIDA CBdms   Status  DP  6/9/1   DC  6/9/5   0   Y
TLRUIDA CBdms   Status  DP  6/10/1  DC  6/10/5  0   Y
TLRUIDA CBdms   Status  DP  6/11/1  DC  6/11/5  0   Y
TLRUIDA CBdms   Status  DP  6/12/1  DC  6/12/5  0   Y   
share|improve this answer
    
thanks ...but u just notice one thing... my output format will remain same... i mean the gaps in between words..... if there are 8spaces between two words then it will remain same. but ypur answer changes the format of the output – pmaipmui Jan 21 at 11:09
    
@pmaipmui it depends on what you want. You can't have it both ways. If you always want exactly 8 spaces between the columns, then the columns cannot be aligned if they can have different widths. The reason you have the alignment problem is precisely because you always have 8 spaces. You can't both always have 8 spaces and fic the alignment. Which one do you want? – terdon Jan 21 at 11:22

we have very simple command for that:

tr -s ' ' <input-file >output-file

-s option removes the occurrence of <space> (or any character following it on command line for that matter)

share|improve this answer

If you want nice columns in the terminal output, you should not use spaces but characters called "TAB". An sed oneliner that replaces all your spaces with TABs is the following

sed -i -e "s/\s\+/\t/g" your_input_file
share|improve this answer
    
you command is not working – pmaipmui Jan 21 at 9:25
    
Eek! The bug is fixed now. I should test even the simplest oneliner before posting it. – jknappen Jan 21 at 9:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.