Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I want to replace the 5th line of multiple text files (file1.txt,file2.txt,file3.txt,file4.txt) with the string " Good Morning " using a single terminal command.

All the text files are located on my ~/Desktop.

Note: My desktop consists of 6 .txt files.I want to apply the change to above mentioned 4 text files only.

share|improve this question

2 Answers 2

up vote 14 down vote accepted

Here are a few approaches. I am using brace expansion (file{1..4}) which means file1.txt file2.txt file3.txt file4.txt

  1. Perl

    perl -i -pe 's/.*/ Good Morning / if $.==5' file{1..4}.txt
    

    Explanation:
    -i : causes perl to edit the files in place, changing the original file.
    -p : means read the input file line by line, apply the script and print it
    -e : allows you to pass a script from the command line
    s/.*/ Good Morning / : That will replace the text in the current line (.*) with Good Morning
    $. is a special Perl variable that holds the current line number of the input file. So, s/foo/bar/ if $.==5, means replace foo with bar only on the 5th line.

  2. sed

    sed -i '5s/.*/ Good Morning /' file{1..4}.txt
    

    Explanation:
    -i : Like for perl, edit file in place.
    By default, sed prints each line of the input file. The 5s/pattern/replacement/ means substitute pattern with replacement on the 5th line.

  3. awk

    for f in file{1..4}.txt; do 
        awk 'NR==5{$0=" Good Morning "}1;' "$f" > foobar && mv foobar "$f"; 
    done
    

    Explanation:
    awk has no equivalent to the -i option1 which means that we need to create a temporary file (foobar) which is then renamed to overwrite the original. The bash loop for f in file{1..4}.txt; do ... ; done simply goes through each of file{1..4}.txt, saving the current file name as $f. In awk, NR is the current line number and $0 is the content of the current line. So, the script will replace the line ($0) with " Good Morning " only on the 5th line. 1; is awk for "print the line".

    1Newer versions do as devnull showed in his answer.

  4. coreutils

    for f in file{1..4}.txt; do 
        (head -4 "$f"; echo " Good Morning "; tail -n +6 "$f") > foobar && 
        mv foobar "$f"; 
    done 
    

    Explanation:
    The loop is explained in the previous section.
    head -4 : print the first 4 lines
    echo " Good Morning ": print " Good Morning "
    tail -n +6 : print everything from the 6th line to the end of the file
    The parentheses ( ) around those three commands allow you to capture the output of all three (so, 1st 4 lines, then " Good morning ", then the rest of the lines) and redirect them to a file.

    `

share|improve this answer

You could use sed:

sed '5s/^/Good morning /' file

would append Good morning on the fifth line of a file.

If you want to replace the contents on line 5 instead, say:

sed '5s/.*/Good morning/' file

If you wanted to save the changes to the file in-place, use the -i option:

sed -i '5s/.*/Good morning/' file

sed can handle more than one file at a time. You can just add more filenames onto the end of the command. You can also use bash expansions to match particular files:

# manually specified
sed -i '5s/.*/Good morning/' file1.txt file2.txt file3.txt file4.txt

# wildcard: all files on the desktop
sed -i '5s/.*/Good morning/' ~/Desktop/*

# brace expansion: file1.txt, file2.txt, file3.txt, file4.txt
sed -i '5s/.*/Good morning/' file{1..4}.txt

You can read more about brace expansions here.


GNU awk versions 4.1.0 and higher come with an extension that enable in-place editing. So you could say:

gawk -i inplace 'NR==5{$0="Good morning"}7' file

to replace line #5 in the file with Good morning!

share|improve this answer

Your Answer

 
discard

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.