Print lines based on line number and specified condition


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Print lines based on line number and specified condition
# 8  
Old 12-31-2014
Code:
awk -F"," 'BEGIN{c=3} {for (i=1;i<=NF;i++) { printf i%c ? i!=NF ? $i FS : $i"\n" :  $i"\n"}}' filename

# 9  
Old 12-31-2014
Try:
Code:
tr , '\n' < file | paste -d, - - -

# 10  
Old 12-31-2014
Quote:
Originally Posted by Anjan1
Hi,

I have a file like below.

Code:
1,2,3,4,5,6,7,8,9

I would like to print or copied to a file based of line count in perl

If I gave a condition 1 to 3 then it should iterate over above file and print 1 to 3 and then again 1 to 3 etc.

output should be

Code:
1,2,3
4,5,6
7,8,9

Not so elegant as some of the other solutions...but your code preference might be Perl.
With this example, you can give the number of output columns on the command line (optional).
The output goes to screen and file (./result.txt).
Code:
#!/usr/bin/perl

use warnings;
use strict;

my @result;
my $i;
my $line;
my $cols;

## Usage: command [number of columns]
if ( ! $ARGV[0] ) {
    $cols = 3;     # defaults to 3 columns if none given
} else {
    $cols = $ARGV[0];
}

my $infil = "new_num.txt";
my $outfil = "result.txt";
open ( my $fin, '<', "$infil" ) or die "Cannot read the file $infil: $!\n";
open ( my $fout, '>', "$outfil" ) or die "Cannot read the file $outfil: $!\n";

#START:
while ( $line = <$fin> ) {
    chomp ( $line );
    @result = split (",", $line);
    my $sz = $#result;
    foreach (@result) {
        $i += 1;
        print ($_);
        print $fout ($_);
        if ( $i % $cols != 0 ) {
            print (",") if not ( $i > $sz );
            print $fout (",") if not ( $i > $sz );
        }else{
            print ("\n");
            print $fout ("\n");
        }
    }
    if ( $i % $cols ) {
        print ("\n");
        print $fout ("\n");
    }
    $i = 0;
}
close $fout;
close $fin;

#  output
# (3 cols)
# ~~~~~~
# 1,2,3
# 4,5,6
# 7,8,9

# (multi-line)
# ~~~~~~
# a,b,c
# d,e,f
# g,h,i
# j,k,l
# m,n,o
# p,q,r
# s,t,u
# v,w,x
# y,z
# 0,1,2
# 3,4,5
# 6,7,8
# 9
# A,B,C
# D,E,F

Multi-line data as in Don Cragun's post (#11)
Code:
a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
0,1,2,3,4,5,6,7,8,9
A,B,C,D,E,F

Six column output...
Code:
a,b,c,d,e,f
g,h,i,j,k,l
m,n,o,p,q,r
s,t,u,v,w,x
y,z
0,1,2,3,4,5
6,7,8,9
A,B,C,D,E,F


Last edited by ongoto; 12-31-2014 at 08:18 PM.. Reason: adjusted for multi-line input; corrected $ARGV test
# 11  
Old 12-31-2014
Quote:
Originally Posted by Anjan1
ravinder singh can you please explain me your awk code.
I assume Ravinder didn't reply to this because you pointed out that it didn't work correctly if the number of input fields wasn't an exact multiple of the number of desired fields on each output line (and he gave you an xargs solution that worked as you requested).

Here is a slightly modified version of his script that will print the missing data at the end of an input line and allows you to set the desired number of output fields (as in ongoto's perl script):
Code:
#!/bin/ksh
FieldsPerLine=${1:-3}			# Set the number of fields to be placed
					# on each output line with a default of
					# 3 if no operands are given.
awk -F, -v fpl="$FieldsPerLine" '	# Set input field separator to comma and
					# set "fpl" to the number of fields to put
					# on each output line.
{	for(i=1;i<=NF;i++){		# For each input field...
		S=((S!="")?S OFS $i:$i)	# If string "S" is not an empty string,
					# set string "S" to the current 
					# contents of "S" followed by the 
					# output field separator followed by the
					# contents of the current field; 
					# otherwise, set string "S" to the 
					# contents of the current field.
		if(i%fpl==0){		# If the current field # is evenly
					# divisible by the specified number of
					# fields per output line...
			print S;S=""	# Print the current contents of the
					# string "S" and clear the contents of
					# "S".
		}
	}
	if(NF%fpl){			# If the number of fields on this input
					# line is not evenly divisible by the
					# specified of fields per output line...
		print S;S=""		# Print the remaining fields for this
					# line and clear the contents of "S".
	}
}' OFS=, Input_file			# Set output field separator to comma
					# and specify the input file to be
					# processed.

The code shown in red is what I changed from Ravinder's original script:
  • The FieldsPerLine shell variable and the fpl awk variable processing allows you to specify the desired number of output fields/line instead of always using the default value (3).
  • The change from S=S?S OFS $i:$i)to:S=((S!="")?S OFS $i:$i) corrects a bug that will only be seen if the 1st field on an output line was from an input field that was a string of one or more zeroes.
  • The if statement added after the for loop takes care of the missing output lines from input lines that do not contain an even multiple of the number of fields desired in output lines.

This was written and tested using the Korn shell, but it will also work with any other shell that recognizes basic POSIX parameter expansion requirements (such as bash). As with any standard awk script, if you want to try this on a Solaris/SunOS system, change awk to /usr/xpg4/bin/awk, /usr/xpg6/bin/awk, or nawk.

If Input_file contains:
Code:
a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
0,1,2,3,4,5,6,7,8,9
A,B,C,D,E,F

the default output produced by this script is:
Code:
a,b,c
d,e,f
g,h,i
j,k,l
m,n,o
p,q,r
s,t,u
v,w,x
y,z
0,1,2
3,4,5
6,7,8
9
A,B,C
D,E,F

and if run with a different requested number of fields per output line such as with ./splitline 5, it produces the output:
Code:
a,b,c,d,e
f,g,h,i,j
k,l,m,n,o
p,q,r,s,t
u,v,w,x,y
z
0,1,2,3,4
5,6,7,8,9
A,B,C,D,E
F

These 2 Users Gave Thanks to Don Cragun For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Reading a file line by line and print required lines based on pattern

Hi All, i want to write a shell script read below file line by line and want to exclude the lines which contains empty value for MOUNTPOINT field. i am using centos 7 Operating system. want to read below file. # cat /tmp/d5 NAME="/dev/sda" TYPE="disk" SIZE="60G" OWNER="root"... (4 Replies)
Discussion started by: balu1234
4 Replies

2. Shell Programming and Scripting

Print certain lines based on condition

Hi All, I have following listing Filesystem GB blocks Free Used Iused Iused Mounted on /dev/hd2 4.00 0.31 93 63080 43 /usr Filesystem GB blocks Free Used Iused Iused Mounted on Filesystem GB blocks Free Used Iused Iused... (11 Replies)
Discussion started by: ckwan
11 Replies

3. Shell Programming and Scripting

Sed print range of lines between line number and pattern

Hi, I have a file as below This is the line one This is the line two <\XMLTAG> This is the line three This is the line four <\XMLTAG> Output of the SED command need to be as below. This is the line one This is the line two <\XMLTAG> Please do the need to needful to... (4 Replies)
Discussion started by: RMN
4 Replies

4. Shell Programming and Scripting

print lines between line number

Hi, Anyone help me to print the lines from the flat file between 879th line number and 1424th line number. The 879 and 1424 should be passed as input to the shell script(It should be dynamic). Can any one give me using sed or awk? I tried using read, and print the lines..Its taking too... (3 Replies)
Discussion started by: senthil_is
3 Replies

5. Shell Programming and Scripting

join based on line number when one file is missing lines

I have a file that contains 87 lines, each with a set of coordinates (x & y). This file looks like: 1 200.3 -0.3 2 201.7 -0.32 ... 87 200.2 -0.314 I have another file which contains data that was taken at certain of these 87 positions. i.e.: 37 125 42 175 86 142 where the first... (1 Reply)
Discussion started by: jackiev
1 Replies

6. Shell Programming and Scripting

Merge two non-consecutive lines based on line number or string

This is a variation of an earlier post found here: unixcom/shell-programming-scripting/159821-merge-two-non-consecutive-lines.html User Bartus11 was kind enough to solve that example. Previously, I needed help combining two lines that are non-consecutive in a file. Now I need to do the... (7 Replies)
Discussion started by: munkee
7 Replies

7. Shell Programming and Scripting

Delete lines based on line number

I have a file with ~200K lines, I need to delete 4K lines in it. There is no range. I do have the line numbers of the lines which I want to be deleted. I did tried using > cat del.lines sed '510d;12d;219d;......;3999d' file > source del.lines Word too long. I even tried... (2 Replies)
Discussion started by: novice_man
2 Replies

8. Shell Programming and Scripting

awk to print lines based on string match on another line and condition

Hi folks, I have a text file that I need to parse, and I cant figure it out. The source is a report breaking down softwares from various companies with some basic info about them (see source snippet below). Ultimately what I want is an excel sheet with only Adobe and Microsoft software name and... (5 Replies)
Discussion started by: rowie718
5 Replies

9. Shell Programming and Scripting

Print selection of line based on line number

Hi Unix gurus Basically i am searching for the pattern and getting the line numbers of the grepped pattern. I am trying to print the series of lines from 7 lines before the grepped line number to the grepped line number. I am trying to use the following code. but it is not working. cat... (3 Replies)
Discussion started by: mohanm
3 Replies

10. Shell Programming and Scripting

searching and storing unknown number of lines based on the string with a condition

Dear friends, Please help me to resolve the problem below, I have a file with following content: date of file creation : 12 feb 2007 ==================== = name : suresh = city :mumbai #this is a blank line = date : 1st Nov 2005 ==================== few lines of some text this... (7 Replies)
Discussion started by: swamymns
7 Replies
Login or Register to Ask a Question