Linux add line to text file

How to insert a text at the beginning of a file?

It’s similar but I don’t want to create any new line with it. I would like to do this with sed if possible.

19 Answers 19

sed can operate on an address:

What is this magical 1s you see on every answer here? Line addressing!.

Want to add on the first 10 lines?

$ < echo -n ''; cat file; > >file.new $ mv file

-i stands for in-place, you can append a suffix to -i to make a copy rather than overwrite. -i.new would make a new file ending with .new, but just -i would edit the file directly.

Note that the sed won’t work on an empty file — afaict sed can’t be made to do anything at all with 0-length input.

If you want to add a line at the beginning of a file, you need to add \n at the end of the string in the best solution above.

The best solution will add the string, but with the string, it will not add a line at the end of a file.

On Mac OS, was getting error with «undefined label». Found that you need to give an extension for a backup file; see mkyong.com/mac/…

Under Mac OS’s sed version you have to supply backup file name with -i option. One can pass just an empty string for no backup like sed -i » ‘1s/^/new test\n/’ filename

If the file is only one line, you can use:

sed 's/^/insert this /' oldfile > newfile 

If it’s more than one line. one of:

sed '1s/^/insert this /' oldfile > newfile sed '1,1s/^/insert this /' oldfile > newfile 

I’ve included the latter so that you know how to do ranges of lines. Both of these «replace» the start line marker on their affected lines with the text you want to insert. You can also (assuming your sed is modern enough) use:

sed -i 'whatever command you choose' filename 
echo "$(echo -n 'hello'; cat filename)" > filename 

Unfortunately, command substitution will remove newlines at the end of file. So as to keep them one can use:

echo -n "hello" | cat - filename > /tmp/filename.tmp mv /tmp/filename.tmp filename 

Neither grouping nor command substitution is needed.

This is the superior and simpler solution to all the other ones using sed , which don’t work for empty files.

printf '%s' "some text at the beginning" | cat - filename 

This would only output the text followed by the file’s content, but it does not modify the file at all.

That’s a good solution, I wonder why it didn’t get any upvotes. Here’s mine my good sir. Also, why printf and not a simple echo ?

I tried directing this into a file by appending > file to the command, it jus spammed my terminal with «some text at the beginning»

sed -i '1i /path/of/file.sh' filename 

This will work even is the string containing forward slash «/»

To add a line to the top of the file:

Note that on OS X, sed -i file , fails. However, if you provide a backup extension, sed -i old file , then file is modified in place while file.old is created. You can then delete file.old in your script.

Читайте также:  Ping range ip linux

I’ve found macOS sed wants a dot to edit in place without creating a backup: sed -i. file

echo "your header" > headerFile.txt cat yourFile >> headerFile.txt 

PROBLEM: tag a file, at the top of the file, with the base name of the parent directory.

/mnt/Vancouver/Programming/file1 

tag the top of file1 with Programming .

SOLUTION 1 — non-empty files:

bn=$ ## bn: basename sed -i '1s/^/'"$bn"'\n/'

1s places the text at line 1 of the file.

SOLUTION 2 — empty or non-empty files:

printf "$\n" | cat - > temp && mv -f temp

Note that the — in the cat command is required (reads standard input: see man cat for more information). Here, I believe, it’s needed to take the output of the printf statement (to STDIN), and cat that and the file to temp . See also the explanation at the bottom of http://www.linfo.org/cat.html.

I also added -f to the mv command, to avoid being asked for confirmations when overwriting files.

To recurse over a directory:

for file in *; do printf "$\n" | cat - $file > temp && mv -f temp $file; done 

Note also that this will break over paths with spaces; there are solutions, elsewhere (e.g. file globbing, or find . -type f . -type solutions) for those.

ADDENDUM: Re: my last comment, this script will allow you to recurse over directories with spaces in the paths:

#!/bin/bash ## https://stackoverflow.com/questions/4638874/how-to-loop-through-a-directory-recursively-to-delete-files-with-certain-extensi ## To allow spaces in filenames, ## at the top of the script include: IFS=$'\n'; set -f ## at the end of the script include: unset IFS; set +f IFS=$'\n'; set -f # ---------------------------------------------------------------------------- # SET PATHS: IN="/mnt/Vancouver/Programming/data/claws-test/corpus test/" # https://superuser.com/questions/716001/how-can-i-get-files-with-numeric-names-using-ls-command # FILES=$(find $IN -type f -regex ".*/7*") ## recursive; numeric filenames only FILES=$(find $IN -type f -regex ".*/[0-9 ]*") ## recursive; numeric filenames only (may include spaces) # echo '$FILES:' ## single-quoted, (literally) prints: $FILES: # echo "$FILES" ## double-quoted, prints path/, filename (one per line) # ---------------------------------------------------------------------------- # MAIN LOOP: for f in $FILES do # Tag top of file with basename of current dir: printf "[top] Tag: $\n\n" | cat - $f > temp && mv -f temp $f # Tag bottom of file with basename of current dir: printf "\n[bottom] Tag: $\n" >> $f done unset IFS; set +f 

Источник

Command to append line to a text file without opening an editor

You can append a line of text to a file by using the >> operator:

echo "hello world" >> my_file.txt 
echo "alias list='ls -cl --group-directories-first'" >> config.fish 

I use echo myself, but be careful, if you only specify one > then the file will truncate, not append. for a safer command you can use sed: sed -i ‘$a hello world’ filename

explanation: -i will update the file (otherwise it will just print the result to stdout), $ is regex that will match the end of the file, and a appends the following text to filename.

echo «hello world» >> my_file.txt does not create a new last line with HW , but add it to the string of the last line.

Maybe «Hello World» @7wp 🙂 It’s echo that adds the line break (making it a line as opposed to just a bunch of characters). You can switch off the line break at the end with -n .

Читайте также:  Work with python at linux

Adding to Stefano’s answer, you can also use cat :

$ cat >> config.fish alias list='ls -cl --group-directories-first' > EOF 

I often use this method but recently got caught when I pasted in a text that included some (escape) codes. It didn’t complain but when I checked the file there were chunks of pasted text missing. So use it with care!

@elmclose Sorry, which method? They work differently with respect to metacharacters. I think the second one doesn’t do anything with them, though there might be a few exceptions.

I meant EOF method. Very convenient and useful when you type or paste in readable text. But codes in my text confused the process. The file was a bash script that kept failing. Took me a while before I discovered what had happened.

There’s plenty of methods of appending to file without opening text editors, particularly via multiple available text processing utilities in Ubuntu. In general, anything that allows us to perform open() syscall with O_APPEND flag added, can be used to append to a file.

    GNU version of dd utility can append data to file with conv=notrunc oflag=append

printf "\nalias list='ls -cl --group-directories-first'\n" | dd conv=notrunc oflag=append bs=1 of=config.fish 
sed -i '$a alias list='"'"'ls -cl --group-directories-first'"'" config.fish 
 #!/usr/bin/env python3 # read bytes from stdin, append to specified file import sys with open(sys.argv[1],'ab') as f: f.write(sys.stdin.buffer.read()) 

See also:

Источник

How to append multiple lines to a file

I am writing a bash script to look for a file if it doesn’t exist then create it and append this to it:

Host localhost ForwardAgent yes 

10 Answers 10

# possibility 1: echo "line 1" >> greetings.txt echo "line 2" >> greetings.txt # possibility 2: echo "line 1 line 2" >> greetings.txt # possibility 3: cat > greetings.txt line 1 line 2 EOT # possibility 4 (more about input than output): arr=( 'line 1' 'line 2' ); printf '%s\n' "$" >> greetings.txt 

If sudo (other user privileges) is needed to write to the file, use this:

# possibility 1: echo "line 1" | sudo tee -a greetings.txt > /dev/null # possibility 3: sudo tee -a greetings.txt > /dev/null  

@ott-- You don't need a real subshell (i.e. can save one new process), this is enough: < echo "line 1" ; echo "line 2"; >>>greetings.txt

echo -e "Hello \nWorld \n" >> greetings.txt 
printf '%s\n %s\n' 'Host localhost' 'ForwardAgent yes' >> file.txt 

Or, if it's a literal tab that you want (rather than the four spaces in your question):

printf '%s\n\t%s\n' 'Host localhost' 'ForwardAgent yes' >> file.txt 

You can achieve the same effect with echo , but exactly how varies from implementation to implementation, whereas printf is consistent.

Another approach is to use tee

A few choice lines from tee 's man page:

The tee utility copies standard input to standard output, making a copy in zero or more files.

-a - Append the output to the files rather than overwriting them.

+1 tee tends to work with paths that require sudo (solutions that use > >> <

Here is an example to append multiple lines in a file:

< echo ' directory "/var/cache/bind";' echo ' listen-on < 127.0.0.1; >;' echo ' listen-on-v6 < none; >;' echo ' version "";' echo ' auth-nxdomain no;' echo ' forward only;' echo ' forwarders < 8.8.8.8; 8.8.4.4; >;' echo ' dnssec-enable no;' echo ' dnssec-validation no;' > >> your_file.txt 

It is worth to note that this variant is part of the ShellCheck recommendation github.com/koalaman/shellcheck/wiki/SC2129

SED can append a line to the end of a file like so:

sed -i '$ a text to be inserted' fileName.file
$ selects end of file, the a tells it to append, and after this comes the text that is to be inserted. Then of course the file name.

Does this approach have any added benefit than other solutions?
Yes, this approach has the added benefit of appending to any files return in a search, such as this: find . -name "*.html" -exec sed -i '$ a ' <> \;

I used the above example to insert the ending html tag that was missing on every html page within a number of directories.

Источник

Append text to file from command line without using io redirection

this sounds like an XY problem (perlmonks.org/index.pl?node_id=542341), why do you need append without redirection?

@Joel : could be true. I asked the question for a colleague, and really don't know what the exact problem is.

Typically useful when manipulating files with sudo (the IO are under the user's environment), and you sometimes have a limited set of tools allowed via sudo.

5 Answers 5

If you don't mind using sed then,

$ cat test this is line 1 $ sed -i '$ a\this is line 2 without redirection' test $ cat test this is line 1 this is line 2 without redirection

As the documentation may be a bit long to go through, some explanations :

  • -i means an inplace transformation, so all changes will occur in the file you specify
  • $ is used to specify the last line
  • a means append a line after
  • \ is simply used as a delimiter

I get sed: -i may not be used with stdin on macOS 13.3 bash shell. Probably cos of stackoverflow.com/a/21243111/259453

If you just want to tack something on by hand, then the sed answer will work for you. If instead the text is in file(s) (say file1.txt and file2.txt):

perl -e 'open(OUT, ">>", "outfile.txt"); print OUT while (<>);' file*.txt

N.B. while the >> may look like an indication of redirection, it is just the file open mode, in this case "append".

You can use the --append feature of tee :

cat file01.txt | tee --append bothFiles.txt cat file02.txt | tee --append bothFiles.txt 
cat file01.txt file02.txt | tee --append bothFiles.txt 

I assume the request for no redirection ( >> ) comes from the need to use this in xargs or similar. So if that doesn't count, you can mute the output with >/dev/null .

Piping will also step out of xargs.. So not much better than >> , the best approach here is using sh -c

@Tofandel, I meant before xargs . You can pipe as much as you want before xargs ; but >> will require you to end the pipe, which then can't continue to xargs .

You can use Vim in Ex mode:

I like the approach in this answer, but it doesn't seem to append to the file. A simple example like this: for fidx in $(seq 1 6); do ex -sc "a|Something$" -cx test.txt; done produces text that is not ordered:cat test.txt Something2 Something1 Something3 Something4 Something5 Something6. How do I make it go to the end of the file before appending? Interestingly, it only seems to happen for the first two lines of an empty file. If I run the example multiple times everything is ordered correctly.

Try putting a $ before the a, which references the end of the file: ex -sc "$a|Something$" -cx test.txt

Источник

Оцените статью
Adblock
detector