Linux append to all files

How can I append and prepend some text to all files in a folder in Linux

I have the folder structure like below resources/folder1 , /folder2 , /folder3 Now I want this text to be prepended with newlines:

4 Answers 4

Change directory to resources , create two template files: BEGIN and END .

File: BEGIN

File: END

Run commands:

sed -i '1s/^/\n/' */* sed -i -e '1rBEGIN' -e '$rEND' */* sed -i '1d' */* 

No backslashs escaping any more, this solution is very clear and simple and scales well.

Thanks buddy that worked. That was very easy and simple to understand. only problem is it give error when there is subdirecory as it tries to apply to that as well

Looks like a great solution but doesn’t work for my case. I want to do it in the current directory and only to certain file type.

You can make that with sed :

 sed -i -e " 1s/^/\n\n\n/ ; $s/$/\n/ " $(ls -R resources/folder* ) 

There are probably a myriad ways to do it. Subject to the file names not containing spaces or the like, then you can use:

find resources -type f -print | while read file do < echo "" echo "" cat $file echo "" > > tmp.$$ cp tmp.$$ $file rm -f tmp.$$ done 

The set of braces performs I/O redirection on the enclosed commands. They’re a little tricky to use accurately on the same line as commands, but the code above is easy. The redirection to tmp.$$ is OK if you are not working in a hostile environment; you might need to use mktemp or some other command if you think people might be subverting you while you run the script. The cp and rm done as shown means that you don’t run into problems if any of the files is actually a symlink (or a hard link); the links are preserved. Alternatives such as mv tmp.$$ $file would break links or symlinks.

Источник

Append some text to the end of multiple files in Linux

How can I append the following code to the end of numerous php files in a directory and its sub directory:

 
bash : *.php: ambiguous redirect 

6 Answers 6

I usually use tee because I think it looks a little cleaner and it generally fits on one line.

This is a Dantastic answer. 🙂 And since the OP is using bash, setting globstar will also allow it to handle PHP files in subdirectories.

what if i need to append a string to multiple specific files. I have multiple wordpress installs, and I need to add a string to the end of every file called functions.php. would this be possible with tee?

Читайте также:  Linux команда вывода сообщения

You don’t specify the shell, you could try the foreach command. Under tcsh (and I’m sure a very similar version is available for bash) you can say something like interactively:

foreach i (*.php) foreach> echo "my text" >> $i foreach> end 

$i will take on the name of each file each time through the loop.

As always, when doing operations on a large number of files, it’s probably a good idea to test them in a small directory with sample files to make sure it works as expected.

Oops .. bash in error message (I’ll tag your question with it). The equivalent loop would be

for i in *.php do echo "my text" >> $i done 

If you want to cover multiple directories below the one where you are you can specify

What about the files in the sub directories? I need to append on it as well. PS: I used the command for i in $a do echo «the code» >> $i done But in all files it appended twice and nothing happened to the files in the sub directories.

BashFAQ/056 does a decent job of explaining why what you tried doesn’t work. Have a look.

Since you’re using bash (according to your error), the for command is your friend.

for filename in *.php; do echo "text" >> "$filename" done 

If you’d like to pull «text» from a file, you could instead do this:

for filename in *.php; do cat /path/to/sourcefile >> "$filename" done 

Now . you might have files in subdirectories. If so, you could use the find command to find and process them:

find . -name "*.php" -type f -exec sh -c "cat /path/to/sourcefile >> <>" \; 

The find command identifies what files using conditions like -name and -type , then the -exec command runs basically the same thing I showed you in the previous «for» loop. The final \; indicates to find that this is the end of arguments to the -exec option.

You can man find for lots more details about this.

The find command is portable and is generally recommended for this kind of activity especially if you want your solution to be portable to other systems. But since you’re currently using bash , you may also be able to handle subdirectories using bash’s globstar option:

shopt -s globstar for filename in **/*.php; do cat /path/to/sourcefile >> "$filename" done 

You can man bash and search for «globstar» for more details about this. This option requires bash version 4 or higher.

NOTE: You may have other problems with what you’re doing. PHP scripts don’t need to end with a ?> , so you might be adding HTML that the script will try to interpret as PHP code.

Читайте также:  Линукс разработка графического интерфейса

Источник

Append lines to beginning of all files in a directory

I am trying to prepend two lines to the beginning of all the files in a directory. I can do it for an individual file using the following command:

echo -e "% First Line\n% "$(date)"\n\n$(cat file1.txt)">file1.txt 

Your question is very unclear. «Append» means to add on to existing content, at the end. «Prepend» means to insert before existing content, at the beginning. «Overwrite» means to remove all existing content and replace with the new content. You are asking about all three things as though they are the same. Please edit your question.

3 Answers 3

echo -e "% First Line\n% "$(date)"\n\n$(cat file1.txt)">file1.txt 

This is highly not recommended. If your file contains any backslashes at all you will be in trouble. Please read up on quoting and command substitution.

For a single file, the recommended POSIX way to insert lines at the beginning of the file is:

printf '%s\n' 0a 'First line' '2nd line; 3rd line is empty' '' . x | ex file.txt 

0a means «append after line 0.» It’s a command to ex , the POSIX file editor (and another form of the vi editor, incidentally). The . on a line by itself ends the appending. x saves and exits.

To do multiple files all at once, use a for loop and a file glob:

for f in *.txt; do printf '%s\n' 0a '# This line heads all files' . x | ex "$f" done 

Источник

How to prepend a line to all files in a directory?

I have a directory called backup with file extensions *.sql . The thing I want to do is to prepend a line to all sql files in the directory backup . I did echo ‘use my_db;’ >> backup/*.sql , which didn’t work. I tried the below but don’t know what to do next:

ls backup/*.sql | xargs echo "use my_db;" 

3 Answers 3

for sql in backup/*.sql; do sed -i '1i\use my_db;' "$sql" done 
for sql in backup/*.sql; do sed '1i\ use my_db; ' "$sql" >"$sql.bak" && mv "$sql.bak" "$sql" done 

This would do a in-place editing of each .sql file in backup . The editing command inserts a line before the first line in each file.

This assumes that the pattern backup/*.sql only matches the files that you want to edit.

for sql in backup/*.sql; do < echo 'use my_db;'; cat "$sql"; >>"$sql.tmp" && mv "$sql.tmp" "$sql" done 

In this loop, we first output the line that we’d like to prepend to the file, then the contents of the file. This goes into a temporary file which is then renamed.

echo 'use my_db;' >> backup/*.sql 

would expand to something like

echo 'use my_db;' >> backup/file1.sql backup/file2.sql backup/file3.sql 
echo 'use my_db;' backup/file2.sql backup/file3.sql >> backup/file1.sql 

which would append the given strings to backup/file1.sql .

Читайте также:  Linux измерить скорость соединения

Your second command would not modify any files.

IIRC -i implies -s in GNU sed — so it should be possible to skip the loop and just do sed -i ‘1i\user mydb’ backup/*.sql ( ARG_MAX notwithstanding)

Solution

sed -i ‘1 i\use my_db’ backup/*.sql

Explanation

sed -i Keep the changes in the files, do not write them to stdout .

1 — When sed is positioned on the first line.

i — Insert the following line.

backup/*.sql Files on which sed will perform.

Will this overwrite the first line of every file? Is there a way to add to the first line moving the previous first line to the second line?

@ConnorLeech, this will insert the line use my_db as the first line and move the previously first line as the second line after insertion. If you wanted to replace/overwrite the first line, you would use c\use my_db . You can always omit the -i to see what sed does, without doing the permanent changes in file(s).

You could iterate over every file in that folder.

for item in $(ls backup/ | grep "*.sql") do echo "use my_db;" >> $item done 

Four issues: The regular expression *.sql matches a literal * . You should not parse the output of ls . The text is appended, not prepended. The variable expansion is not quoted.

What about parsing an awk output? I will face the same trouble there, even if grep is used to match sql$ as regexp, isn’t it?

@Kusalananda Always better to quote, just in case, but I believe that variables used in redirections are not wordsplit, to be fair. However, Kyrie001, even if $(ls backup/ | grep «*.sql») were to work (which it won’t for 5 issues it has, 3 of which are for using ls ), the intent could’ve been completely captured by using backup/*.sql in its place. i.e. for item in backup/*.sql

As to what those 5 issues are (provided merely to help you improve your coding): 1) ls output is not portable, for example GNU ls now does bash shell quoting by default; 2) depending on how the ls implementation outputs special characters in filenames, you’ll have to parse them or they might even not be recoverable if they were all replaced with ? s; 3) the result is fed line by line and filtered by grep when filenames could consist of more than 1 line; 4) the grep regex is wrong; 5) the output of the whole pipeline is then wordsplit for the for loop.

@JoL No, the shell will not perform word splitting on the expanded value of the variable in that case, but it will perform filename globbing on the value. Having said that, any globbing would already have been performed by the loop head.

Источник

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