I have a long comma-separated delimited file with 20K lines. Here's a sample:


I want to print like the columns with id, number4, number5 and number 6 with tab-delimited setting the condition number4 is greater than 4.0. Here's some sample output:

id         number4           number5           number6
MRTAT_3of3.RTS 5.31274131274131  2.40945646701554  0.676814519398334

4 Answers 4

awk -F , -v OFS='\t' 'NR == 1 || $6 > 4 {print $1, $6, $7, $8}' input.txt

I agree that awk is the best solution. You can do this just in bash with a couple of other tools:

cut -d , -f 2,6,7,8 filename | {
    read header
    tr , $'\t' <<< "$header"
    while IFS=, read -r id num4 num5 num6; do
        # bash can only do integer arithmetic
        if [[ $(bc <<< "$num4 >= 4.0") = 1 ]]; then
           printf "%s\t%s\t%s\t%s\n" "$id" "$num4" "$num5" "$num6"

Really can't beat the awk script above, but here's a ruby solution,


puts "id\tnumber4\tnumber5\tnumber6"

ARGF.each_line do |line|
  arr = line.split(',')
  puts "#{arr[1]}\t#{arr[5]}\t#{arr[6]}\t#{arr[7]}" if arr[5].to_f > 4.0

To use the script call it with the filename or pipe the file into it.


Perl solution:

perl -F, -le '$, = "\t"; print @F[1,5,6,7] if $F[5] > 4 || $. == 1' file

-F, specifies the pattern to split on. -F implicitly sets -a

-a turns on autosplit mode when used with a -n. An implicit split command to the @F array is done as the first thing inside the implicit while loop produced by the -n. -a implicitly sets -n

-n causes Perl to assume the loop around your program, which makes it iterate over filename arguments somewhat like sed -n or awk

-l enables automatic line-ending processing. It has two separate effects. First, it automatically chomps the input record separator (\n). Second, it assigns the output record separator to \n.

-e used to enter one line of program

So, perl -F, -le '$, = "\t"; print @F[1,5,6,7] if $F[5] > 4 || $. == 1' do something like this:

use English;


while (<>) { # iterate over each line of the each file
    @F = split(',');
    print @F[1,5,6,7] if $F[5] > 4 || $INPUT_LINE_NUMBER == 1;
  • To add value to your answer please could you take a few moments to explain how it works.
    – roaima
    Jul 17, 2015 at 23:31
  • @roaima, ok. one moment. Jul 17, 2015 at 23:34
  • 1
    @roaima, done. what do you think? Jul 18, 2015 at 0:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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