Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert a new line at the beginning of a file [duplicate]

Is it any way to find all files like *.js and insert some specific line at the beginning of the file? looking for something like:

find . -name '*.js' -exec sh -c '[insert this 'string'] "${0%.js}"' {} \;

like image 705
Sarkis Arutiunian Avatar asked May 14 '17 23:05

Sarkis Arutiunian


People also ask

How do I add a new line to a file?

Sometimes we need to work with a file for programming purposes, and the new line requires to add at the end of the file. This appending task can be done by using 'echo' and 'tee' commands. Using '>>' with 'echo' command appends a line to a file.

How do you insert a line at the beginning of a file in Unix?

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.

How will you insert a line before the first line?

Use sed 's insert ( i ) option which will insert the text in the preceding line. Also note that some non-GNU sed implementations (for example the one on macOS) require an argument for the -i flag (use -i '' to get the same effect as with GNU sed ).

How can I get two lines of the same file?

Use comm -12 file1 file2 to get common lines in both files. You may also needs your file to be sorted to comm to work as expected. Or using grep command you need to add -x option to match the whole line as a matching pattern. The F option is telling grep that match pattern as a string not a regex match.


2 Answers

Here's a way to add a line to the beginning of a file:

sed -i '1s/^/line_to_be_added\n/' file

Then, you could use the code above with find to achieve your ultimate goal:

find . -type f -name '*.js' -exec sed -i '1s/^/line_to_be_added\n/' {} \;

Note: this answer was tested and works with GNU sed.

Edit: the code above would not work properly on a .js file that is empty, as the sed command above does not work as expected on empty files. A workaround to that would be to test if the file is empty, and if it is, add the desired line via echo, otherwise add the desired line via sed. This all can be done in a (long) one-liner, as follows:

find . -type f -name '*.js' -exec bash -c 'if [ ! -s "{}" ]; then echo "line_to_be_added" >> {}; else sed -i "1s/^/line_to_be_added\n/" {}; fi' \;

Edit 2: As user Sarkis Arutiunian pointed out, we need to add '' before the expression and \'$' before \n to make this work properly in MacOS sed. Here an example

sed -i '' '1s/^/line_to_be_added\'$'\n/' filename.js

Edit 3: This also works, and editors will know how to syntax highlight it:

sed -i '' $'1s/^/line_to_be_added\\\n/' filename.js
like image 77
Jamil Said Avatar answered Oct 12 '22 03:10

Jamil Said


Portability: Use Sed's Hold Space

If you want a solution that works portably with both GNU and BSD sed, use the following to prepend text to the first line, and then pass the rest through unchanged:

sed '1 { x; s/^.*/foo/; G; }' example.txt

Assuming a corpus of:

bar
baz

this will print:

foo
bar
baz

You can save the transformation in a script, and then use find or xargs and the sed -i flag for in-place edits once you're sure everything is working the way you expect.

Caveat

Using sed has one major limitation: if the file is empty, it won't work as you might expect. That's not something that seems likely from your original question, but if that's a possibility then you need to use something like cat <(echo foo) example.txt | sponge example.txt to edit the file in-place, or use temporary files and move them after concatenating them.

NB: Sponge is non-standard. It can be found in the moreutils package.

like image 37
Todd A. Jacobs Avatar answered Oct 12 '22 02:10

Todd A. Jacobs