Skip to main content
replaced http://unix.stackexchange.com/ with https://unix.stackexchange.com/
Source Link

You can do it entirely in the shell with a script like this:

#!/bin/bash
line_num=0
while IFS= read -r line
do
        : $((line_num++))
        if [[ line_num -ge 3  &&  line_num -le 8 ]]
        then
                printf "%s\n" "${line/snow/dry}"
        else
                printf "%s\n" "$line"
        fi
done

(I've tested this in bash, and AndreyAndrey reports that it works in ksh, but it won't work in all POSIX-compliant versions of sh.)  It reads lines from the standard input.  It counts lines (with line_num=0 and : $((line_num++)) because you want to specify a line number range; if that requirement is removed, the statements referencing line_num can be deleted.  The conditional test

        if [[ line_num -ge 3  &&  line_num -le 8 ]]

means “IF (line_num ≥ 3)  AND  (line_num ≤ 8)”, corresponding to the range 3,8, i.e., 3 through 8.  (Which is a point of confusion for Unix newbies, who expect 3,8 to mean “3 and also 8”, and expect “3 through 8” to be represented as 3-8 — i.e., the convention used by print dialog boxes in Windows for printing a subset of the pages of a document.)

On the lines that are in the range, it uses the

        ${parameter/pattern/string)

form of parameter expansion to replace "snow" with "dry" before writing the line out to the standard output.  Lines outside the range are written unmodified.

This will change the first occurrence (if any) of "snow" on each line within the range.  To replace all occurrences, use ${line//snow/dry} (insert an extra / before "snow").

I'm not clear on the big picture of what you want.

  • You could incorporate the above code into your existing script.

  • If you modified your script (let's call it weather.sh) to write to stdout rather than the file, then you could say

      ./weather.sh | ./do_substitute.sh > weatherfile
    
  • If you want to create weatherfile the same way you are doing it now, but then change it afterwards, you could do

      ./do_substitute.sh < weatherfile > weatherfile.tmp
      mv weatherfile.tmp weatherfile
    

You can do it entirely in the shell with a script like this:

#!/bin/bash
line_num=0
while IFS= read -r line
do
        : $((line_num++))
        if [[ line_num -ge 3  &&  line_num -le 8 ]]
        then
                printf "%s\n" "${line/snow/dry}"
        else
                printf "%s\n" "$line"
        fi
done

(I've tested this in bash, and Andrey reports that it works in ksh, but it won't work in all POSIX-compliant versions of sh.)  It reads lines from the standard input.  It counts lines (with line_num=0 and : $((line_num++)) because you want to specify a line number range; if that requirement is removed, the statements referencing line_num can be deleted.  The conditional test

        if [[ line_num -ge 3  &&  line_num -le 8 ]]

means “IF (line_num ≥ 3)  AND  (line_num ≤ 8)”, corresponding to the range 3,8, i.e., 3 through 8.  (Which is a point of confusion for Unix newbies, who expect 3,8 to mean “3 and also 8”, and expect “3 through 8” to be represented as 3-8 — i.e., the convention used by print dialog boxes in Windows for printing a subset of the pages of a document.)

On the lines that are in the range, it uses the

        ${parameter/pattern/string)

form of parameter expansion to replace "snow" with "dry" before writing the line out to the standard output.  Lines outside the range are written unmodified.

This will change the first occurrence (if any) of "snow" on each line within the range.  To replace all occurrences, use ${line//snow/dry} (insert an extra / before "snow").

I'm not clear on the big picture of what you want.

  • You could incorporate the above code into your existing script.

  • If you modified your script (let's call it weather.sh) to write to stdout rather than the file, then you could say

      ./weather.sh | ./do_substitute.sh > weatherfile
    
  • If you want to create weatherfile the same way you are doing it now, but then change it afterwards, you could do

      ./do_substitute.sh < weatherfile > weatherfile.tmp
      mv weatherfile.tmp weatherfile
    

You can do it entirely in the shell with a script like this:

#!/bin/bash
line_num=0
while IFS= read -r line
do
        : $((line_num++))
        if [[ line_num -ge 3  &&  line_num -le 8 ]]
        then
                printf "%s\n" "${line/snow/dry}"
        else
                printf "%s\n" "$line"
        fi
done

(I've tested this in bash, and Andrey reports that it works in ksh, but it won't work in all POSIX-compliant versions of sh.)  It reads lines from the standard input.  It counts lines (with line_num=0 and : $((line_num++)) because you want to specify a line number range; if that requirement is removed, the statements referencing line_num can be deleted.  The conditional test

        if [[ line_num -ge 3  &&  line_num -le 8 ]]

means “IF (line_num ≥ 3)  AND  (line_num ≤ 8)”, corresponding to the range 3,8, i.e., 3 through 8.  (Which is a point of confusion for Unix newbies, who expect 3,8 to mean “3 and also 8”, and expect “3 through 8” to be represented as 3-8 — i.e., the convention used by print dialog boxes in Windows for printing a subset of the pages of a document.)

On the lines that are in the range, it uses the

        ${parameter/pattern/string)

form of parameter expansion to replace "snow" with "dry" before writing the line out to the standard output.  Lines outside the range are written unmodified.

This will change the first occurrence (if any) of "snow" on each line within the range.  To replace all occurrences, use ${line//snow/dry} (insert an extra / before "snow").

I'm not clear on the big picture of what you want.

  • You could incorporate the above code into your existing script.

  • If you modified your script (let's call it weather.sh) to write to stdout rather than the file, then you could say

      ./weather.sh | ./do_substitute.sh > weatherfile
    
  • If you want to create weatherfile the same way you are doing it now, but then change it afterwards, you could do

      ./do_substitute.sh < weatherfile > weatherfile.tmp
      mv weatherfile.tmp weatherfile
    
Clarified test for inclusion in a specified range of lines (e.g., `3-8`).
Source Link

You can do it entirely in the shell with a script like this:

#!/bin/bash
line_num=0
while IFS= read -r line
do
        : $((line_num++))
        if [[ line_num -ge 3  &&  line_num -le 8 ]]
        then
                printf "%s\n" "${line/snow/dry}"
        else
                printf "%s\n" "$line"
        fi
done

(I've tested this in bash, and Andrey reports that it works in ksh, but it won't work in all POSIX-compliant versions of sh.)  It reads lines from the standard input.  It counts lines (with line_num=0 and : $((line_num++)) because you want to specify a line number range; if that requirement is removed, the statements referencing line_num can be deleted.  OnThe conditional test

        if [[ line_num -ge 3  &&  line_num -le 8 ]]

means “IF (line_num ≥ 3)  AND  (line_num ≤ 8)”, corresponding to the range 3,8, i.e., 3 through 8.  (Which is a point of confusion for Unix newbies, who expect 3,8 to mean “3 and also 8”, and expect “3 through 8” to be represented as 3-8 — i.e., the convention used by print dialog boxes in Windows for printing a subset of the pages of a document.)

On the lines that are in the range, it uses the

        ${parameter/pattern/string)

form of parameter expansion to replace "snow" with "dry" before writing the line out to the standard output.  Lines outside the range are written unmodified.

This will change the first occurrence (if any) of "snow" on each line within the range.  To replace all occurrences, use ${line//snow/dry} (insert an extra / before "snow").

I'm not clear on the big picture of what you want.

  • You could incorporate the above code into your existing script.

  • If you modified your script (let's call it weather.sh) to write to stdout rather than the file, then you could say

      ./weather.sh | ./do_substitute.sh > weatherfile
    
  • If you want to create weatherfile the same way you are doing it now, but then change it afterwards, you could do

      ./do_substitute.sh < weatherfile > weatherfile.tmp
      mv weatherfile.tmp weatherfile
    

You can do it entirely in the shell with a script like this:

#!/bin/bash
line_num=0
while IFS= read -r line
do
        : $((line_num++))
        if [[ line_num -ge 3  &&  line_num -le 8 ]]
        then
                printf "%s\n" "${line/snow/dry}"
        else
                printf "%s\n" "$line"
        fi
done

(I've tested this in bash, and Andrey reports that it works in ksh, but it won't work in all POSIX-compliant versions of sh.)  It reads lines from the standard input.  It counts lines (with line_num=0 and : $((line_num++)) because you want to specify a line number range; if that requirement is removed, the statements referencing line_num can be deleted.  On the lines that are in the range, it uses the

${parameter/pattern/string)

form of parameter expansion to replace "snow" with "dry" before writing the line out to the standard output.  Lines outside the range are written unmodified.

This will change the first occurrence (if any) of "snow" on each line within the range.  To replace all occurrences, use ${line//snow/dry} (insert an extra / before "snow").

I'm not clear on the big picture of what you want.

  • You could incorporate the above code into your existing script.

  • If you modified your script (let's call it weather.sh) to write to stdout rather than the file, then you could say

      ./weather.sh | ./do_substitute.sh > weatherfile
    
  • If you want to create weatherfile the same way you are doing it now, but then change it afterwards, you could do

      ./do_substitute.sh < weatherfile > weatherfile.tmp
      mv weatherfile.tmp weatherfile
    

You can do it entirely in the shell with a script like this:

#!/bin/bash
line_num=0
while IFS= read -r line
do
        : $((line_num++))
        if [[ line_num -ge 3  &&  line_num -le 8 ]]
        then
                printf "%s\n" "${line/snow/dry}"
        else
                printf "%s\n" "$line"
        fi
done

(I've tested this in bash, and Andrey reports that it works in ksh, but it won't work in all POSIX-compliant versions of sh.)  It reads lines from the standard input.  It counts lines (with line_num=0 and : $((line_num++)) because you want to specify a line number range; if that requirement is removed, the statements referencing line_num can be deleted.  The conditional test

        if [[ line_num -ge 3  &&  line_num -le 8 ]]

means “IF (line_num ≥ 3)  AND  (line_num ≤ 8)”, corresponding to the range 3,8, i.e., 3 through 8.  (Which is a point of confusion for Unix newbies, who expect 3,8 to mean “3 and also 8”, and expect “3 through 8” to be represented as 3-8 — i.e., the convention used by print dialog boxes in Windows for printing a subset of the pages of a document.)

On the lines that are in the range, it uses the

        ${parameter/pattern/string)

form of parameter expansion to replace "snow" with "dry" before writing the line out to the standard output.  Lines outside the range are written unmodified.

This will change the first occurrence (if any) of "snow" on each line within the range.  To replace all occurrences, use ${line//snow/dry} (insert an extra / before "snow").

I'm not clear on the big picture of what you want.

  • You could incorporate the above code into your existing script.

  • If you modified your script (let's call it weather.sh) to write to stdout rather than the file, then you could say

      ./weather.sh | ./do_substitute.sh > weatherfile
    
  • If you want to create weatherfile the same way you are doing it now, but then change it afterwards, you could do

      ./do_substitute.sh < weatherfile > weatherfile.tmp
      mv weatherfile.tmp weatherfile
    
Updated note on shell compatibility.
Source Link

You can do it entirely in the shell with a script like this:

#!/bin/shbash
line_num=0
while IFS= read -r line
do
        : $((line_num++))
        if [[ line_num -ge 3  &&  line_num -le 8 ]]
        then
                printf "%s\n" "${line/snow/dry}"
        else
                printf "%s\n" "$line"
        fi
done

and, no, this does not need to be run in bash (although I don't know whether ksh will work).(I've tested this in bash, and Andrey reports that it works in ksh, but it won't work in all POSIX-compliant versions of sh.)  It reads lines from the standard input.  It counts lines (with line_num=0 and : $((line_num++)) because you want to specify a line number range; if that requirement is removed, the statements referencing line_num can be deleted.  On the lines that are in the range, it uses the

${parameter/pattern/string)

form of parameter expansion to replace "snow" with "dry" before writing the line out to the standard output.  Lines outside the range are written unmodified.

This will change the first occurrence (if any) of "snow" on each line within the range.  To replace all occurrences, use ${line//snow/dry} (insert an extra / before "snow").

I'm not clear on the big picture of what you want.

  • You could incorporate the above code into your existing script.

  • If you modified your script (let's call it weather.sh) to write to stdout rather than the file, then you could say

      ./weather.sh | ./do_substitute.sh > weatherfile
    
  • If you want to create weatherfile the same way you are doing it now, but then change it afterwards, you could do

      ./do_substitute.sh < weatherfile > weatherfile.tmp
      mv weatherfile.tmp weatherfile
    

You can do it entirely in the shell with a script like this:

#!/bin/sh
line_num=0
while IFS= read -r line
do
        : $((line_num++))
        if [[ line_num -ge 3  &&  line_num -le 8 ]]
        then
                printf "%s\n" "${line/snow/dry}"
        else
                printf "%s\n" "$line"
        fi
done

and, no, this does not need to be run in bash (although I don't know whether ksh will work).  It reads lines from the standard input.  It counts lines (with line_num=0 and : $((line_num++)) because you want to specify a line number range; if that requirement is removed, the statements referencing line_num can be deleted.  On the lines that are in the range, it uses the

${parameter/pattern/string)

form of parameter expansion to replace "snow" with "dry" before writing the line out to the standard output.  Lines outside the range are written unmodified.

This will change the first occurrence (if any) of "snow" on each line within the range.  To replace all occurrences, use ${line//snow/dry} (insert an extra / before "snow").

I'm not clear on the big picture of what you want.

  • You could incorporate the above code into your existing script.

  • If you modified your script (let's call it weather.sh) to write to stdout rather than the file, then you could say

      ./weather.sh | ./do_substitute.sh > weatherfile
    
  • If you want to create weatherfile the same way you are doing it now, but then change it afterwards, you could do

      ./do_substitute.sh < weatherfile > weatherfile.tmp
      mv weatherfile.tmp weatherfile
    

You can do it entirely in the shell with a script like this:

#!/bin/bash
line_num=0
while IFS= read -r line
do
        : $((line_num++))
        if [[ line_num -ge 3  &&  line_num -le 8 ]]
        then
                printf "%s\n" "${line/snow/dry}"
        else
                printf "%s\n" "$line"
        fi
done

(I've tested this in bash, and Andrey reports that it works in ksh, but it won't work in all POSIX-compliant versions of sh.)  It reads lines from the standard input.  It counts lines (with line_num=0 and : $((line_num++)) because you want to specify a line number range; if that requirement is removed, the statements referencing line_num can be deleted.  On the lines that are in the range, it uses the

${parameter/pattern/string)

form of parameter expansion to replace "snow" with "dry" before writing the line out to the standard output.  Lines outside the range are written unmodified.

This will change the first occurrence (if any) of "snow" on each line within the range.  To replace all occurrences, use ${line//snow/dry} (insert an extra / before "snow").

I'm not clear on the big picture of what you want.

  • You could incorporate the above code into your existing script.

  • If you modified your script (let's call it weather.sh) to write to stdout rather than the file, then you could say

      ./weather.sh | ./do_substitute.sh > weatherfile
    
  • If you want to create weatherfile the same way you are doing it now, but then change it afterwards, you could do

      ./do_substitute.sh < weatherfile > weatherfile.tmp
      mv weatherfile.tmp weatherfile
    
Source Link
Loading