[bash] How to replace an entire line in a text file by line number

I have a situation where I want a bash script to replace an entire line in a file. The line number is always the same, so that can be a hard-coded variable.

I'm not trying to replace some sub-string in that line, I just want to replace that line entirely with a new line.

Are there any bash methods for doing this (or something simple that can be thrown into a .sh script).

This question is related to bash text replace sed

The answer is


# Replace the line of the given line number with the given replacement in the given file.
function replace-line-in-file() {
    local file="$1"
    local line_num="$2"
    local replacement="$3"

    # Escape backslash, forward slash and ampersand for use as a sed replacement.
    replacement_escaped=$( echo "$replacement" | sed -e 's/[\/&]/\\&/g' )

    sed -i "${line_num}s/.*/$replacement_escaped/" "$file"
}

Excellent answer from Chepner. It is working for me in bash Shell.

 # To update/replace the new line string value with the exiting line of the file
 MyFile=/tmp/ps_checkdb.flag

 `sed -i "${index}s/.*/${newLine}/" $MyFile`

here
index - Line no
newLine - new line string which we want to replace.


Similarly below code is used to read a particular line in the file. This won't affect the actual file.

LineString=`sed "$index!d" $MyFile` 

here
!d - will delete the lines other than line no $index So we will get the output as line string of no $index in the file.


I actually used this script to replace a line of code in the cron file on our company's UNIX servers awhile back. We executed it as normal shell script and had no problems:

#Create temporary file with new line in place
cat /dir/file | sed -e "s/the_original_line/the_new_line/" > /dir/temp_file
#Copy the new file over the original file
mv /dir/temp_file /dir/file

This doesn't go by line number, but you can easily switch to a line number based system by putting the line number before the s/ and placing a wildcard in place of the_original_line.


You can even pass parameters to the sed command:

test.sh

#!/bin/bash
echo "-> start"
for i in $(seq 5); do
  # passing parameters to sed
  j=$(($i+3))
  sed -i "${j}s/.*/replaced by '$i'!/" output.dat
done
echo "-> finished"
exit 

orignial output.dat:

a
b
c
d
e
f
g
h
i
j

Executing ./test.sh gives the new output.dat

a
b
c
replaced by '1'!
replaced by '2'!
replaced by '3'!
replaced by '4'!
replaced by '5'!
i
j

Given this test file (test.txt)

Lorem ipsum dolor sit amet,
consectetur adipiscing elit. 
Duis eu diam non tortor laoreet 
bibendum vitae et tellus.

the following command will replace the first line to "newline text"

$ sed '1 c\
> newline text' test.txt

Result:

newline text
consectetur adipiscing elit. 
Duis eu diam non tortor laoreet 
bibendum vitae et tellus.

more information can be found here

http://www.thegeekstuff.com/2009/11/unix-sed-tutorial-append-insert-replace-and-count-file-lines/


Let's suppose you want to replace line 4 with the text "different". You can use AWK like so:

awk '{ if (NR == 4) print "different"; else print $0}' input_file.txt > output_file.txt

AWK considers the input to be "records" divided into "fields". By default, one line is one record. NR is the number of records seen. $0 represents the current complete record (while $1 is the first field from the record and so on; by default the fields are words from the line).

So, if the current line number is 4, print the string "different" but otherwise print the line unchanged.

In AWK, program code enclosed in { } runs once on each input record.

You need to quote the AWK program in single-quotes to keep the shell from trying to interpret things like the $0.

EDIT: A shorter and more elegant AWK program from @chepner in the comments below:

awk 'NR==4 {$0="different"} { print }' input_file.txt

Only for record (i.e. line) number 4, replace the whole record with the string "different". Then for every input record, print the record.

Clearly my AWK skills are rusty! Thank you, @chepner.

EDIT: and see also an even shorter version from @Dennis Williamson:

awk 'NR==4 {$0="different"} 1' input_file.txt

How this works is explained in the comments: the 1 always evaluates true, so the associated code block always runs. But there is no associated code block, which means AWK does its default action of just printing the whole line. AWK is designed to allow terse programs like this.


in bash, replace N,M by the line numbers and xxx yyy by what you want

i=1
while read line;do
  if((i==N));then
    echo 'xxx'
  elif((i==M));then
    echo 'yyy'
  else
    echo "$line"
  fi
  ((i++))
done  < orig-file > new-file

EDIT

In fact in this solution there are some problems, with characters "\0" "\t" and "\"

"\t", can be solve by putting IFS= before read: "\", at end of line with -r

IFS= read -r line

but for "\0", the variable is truncated, there is no a solution in pure bash : Assign string containing null-character (\0) to a variable in Bash But in normal text file there is no nul character \0

perl would be a better choice

perl -ne 'if($.==N){print"xxx\n"}elsif($.==M){print"yyy\n"}else{print}' < orig-file > new-file

On mac I used

sed -i '' -e 's/text-on-line-to-be-changed.*/text-to-replace-the=whole-line/' file-name

Examples related to bash

Comparing a variable with a string python not working when redirecting from bash script Zipping a file in bash fails How do I prevent Conda from activating the base environment by default? Get first line of a shell command's output Fixing a systemd service 203/EXEC failure (no such file or directory) /bin/sh: apt-get: not found VSCode Change Default Terminal Run bash command on jenkins pipeline How to check if the docker engine and a docker container are running? How to switch Python versions in Terminal?

Examples related to text

Difference between opening a file in binary vs text How do I center text vertically and horizontally in Flutter? How to `wget` a list of URLs in a text file? Convert txt to csv python script Reading local text file into a JavaScript array Python: How to increase/reduce the fontsize of x and y tick labels? How can I insert a line break into a <Text> component in React Native? How to split large text file in windows? Copy text from nano editor to shell Atom menu is missing. How do I re-enable

Examples related to replace

How do I find and replace all occurrences (in all files) in Visual Studio Code? How to find and replace with regex in excel How to replace text in a column of a Pandas dataframe? How to replace negative numbers in Pandas Data Frame by zero Replacing few values in a pandas dataframe column with another value How to replace multiple patterns at once with sed? Using tr to replace newline with space replace special characters in a string python Replace None with NaN in pandas dataframe Batch script to find and replace a string in text file within a minute for files up to 12 MB

Examples related to sed

Retrieve last 100 lines logs How to replace multiple patterns at once with sed? Insert multiple lines into a file after specified pattern using shell script Linux bash script to extract IP address Ansible playbook shell output remove white space from the end of line in linux bash, extract string before a colon invalid command code ., despite escaping periods, using sed RE error: illegal byte sequence on Mac OS X How to use variables in a command in sed?