Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

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

I want to add the following perl command in my bash script please advice

how to change (reduce by one ) the last number that start with "+" character in file with perl ?

Example of original file   ( before run the perl command )

more file


example of requested output file ( after run the perl command )

more file

share|improve this question
up vote 2 down vote accepted

When I hear "do something on the LAST occurrance of ...", I reach for tac to reverse the lines, and do something on the FIRST occurrance.

tac file | nawk '/^\+/&&!done {$1 = "+" substr($1,2)-1; done=1} 1' | tac

On Solaris, you may not have tac installed. You can implement it like this:

tac() { sed -n -e '1!G' -e '$p' -e h "$@"; }
share|improve this answer
I get this - sed -n -e '1!G' -e '$p' -e h "$@" file | awk '/^\+/&&!done {$1 = "+" substr($1,2)-1; done=1} 1' | sed -n -e '1!G' -e '$p' -e h "$@" awk: syntax error near line 1 awk: bailing out near line 1 ( mybe awk syntax not fit solaris ) ? – yael May 11 '12 at 8:49
@yael, I should have specified, on Solaris use nawk instead of awk. /usr/bin/awk is known as "the old, broken awk". – glenn jackman May 11 '12 at 13:57
now work but not reduce the number --> echo 10 >/var/tmp/file ; sed -n -e '1!G' -e '$p' -e h "$@" file | nawk '/^\+/&&!done {$1 = "+" substr($1,2)-1; done=1} 1' | sed -n -e '1!G' -e '$p' -e h "$@" --> the outout 10 – yael May 11 '12 at 14:16
You specified the number must begin with a "+". Also, you have to define the function, don't just take the function body out of context: echo +10 > tmpfile; tac tmpfile | nawk '/^\+/&&!done {$1 = "+" substr($1,2)-1; done=1} 1' | tac outputs +9 – glenn jackman May 11 '12 at 14:21

You can the following script:

#!/usr/bin/perl -w
use strict;

open(INFILE, "< file") or die( "Can't open input file" );
open(OUTFILE, "> file.out") or die( "Can't open output file" );
my @lines = reverse <INFILE>;
foreach my $line (@lines) {
    if ($line =~ /^\+(\d+)/) {
        $line = "+".($1-1)."\n";
my @lines2 = reverse @lines;
foreach my $line (@lines2) {
    print OUTFILE $line;
share|improve this answer
yes but the original question is to add this command in my bash , I don't want different perl script – yael May 10 '12 at 13:03
What can't you call the perl script from bash? Yeah, you can make Khaled's script into a one-liner inside a bash script, but that would horrible. – cjc May 10 '12 at 13:15

Your Answer


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.