Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I need to add PHP tags surrounding a file. It's easy to append them using

find . -exec echo "?>" >> '{}' \;

but how can I prepend the tag <?php?

share|improve this question

migrated from superuser.com Sep 12 '11 at 22:28

This question came from our site for computer enthusiasts and power users.

7 Answers 7

up vote 16 down vote accepted
sed -i "1s/^/<?php /" file

(The -i is for in-place edit.)

More portable version:

ed file <<!
1s/^/<?php /
wq
!
share|improve this answer
    
+1, neat. –  nik Sep 6 '09 at 10:20
    
nifty - that's a bit easier than what I was about to describe :) –  warren Sep 6 '09 at 14:07
    
I need to add the extension to the -i argument here. Are you using sed or GNU sed? –  Richard Hoskins Sep 6 '09 at 21:52
2  
I'm using BSD sed, and it allows in place editing, but I need to give it an extension. i.e. 'sed -i .bak "PATTERN" file' –  Richard Hoskins Sep 8 '09 at 16:37
3  
-i is not portable, the syntax differs between implementations, and it breaks symlinks. You'd be better off using an application that is actually designed to edit files. –  Chris Down Sep 18 '11 at 12:37

You could use an AWK filter like this,

awk '{if(NR==1) printf "%s%s","PREFIX",$0; else print $0}' testfile > newfile

Where PREFIX is your php prefix string.

share|improve this answer

I can't leave a comment yet, but to do it all in one step:

find . -type f -exec sed -i -e "1s/^/<?php /" -e "\$s/\$/ ?>/" {} \;
share|improve this answer
    
+1 very cool, thank you. –  user2362 Sep 6 '09 at 16:17
    
Love it, saved me hours. –  Stephen Orr Sep 25 at 10:08

You can do that with a perl one-liner:

perl -0777 -p -i -e "s/^/hey /g" testfile

The -0777 forces file-slurping mode, so the entire file is read as one line. -p enables looping. -i enables in-place editing of the file. ^ indicates the beginning of a line.

$ cp testfile1 testfile; perl -0777 -p -i -e "s/^/hey /g" testfile; diff testfile testfile1
1c1
< hey asdf
---
> asdf

Update: As indicated in the comments, you can choose to auto-generate a backup by using -i.bak instead of -i. This provides additional safety in case of errors in your command. The argument to -i becomes the suffix of the backup.

When updating a bunch of files, you could run the command with -i.backup${RANDOM}, check that all files updated correctly, then remove all files with that extension.

share|improve this answer
1  
"The value 0777 will cause Perl to slurp files whole because there is no legal byte with that value" see sial.org/howto/perl/one-liner/#s3.5 –  Chris W. Rea Sep 6 '09 at 12:40
1  
If you recommend use of the -i flag without a suffix, please warn readers that this means you get no backup. For a few characters more (-i.bak), you get a backup in case your one-liner includes a typo. A fairly simple typo (say, forgetting the -p flag) can ruin your whole day otherwise. –  Telemachus Sep 6 '09 at 14:19
    
@Telemachus - Agreed. Updated. –  nagul Sep 6 '09 at 14:36

sed is for editing streams -- a file is not a stream. Use a program that is meant for this purpose, likeed or ex. The -i option to sed is not only not portable, it will also break any symlinks you may encounter, since it essentially deletes it and recreates it, which is pointless.

for file in foo bar baz; do
    ed -s "${file}" << EOF
0a
<?php 
.
w
EOF
done
share|improve this answer
    
What you presented is a basic way to edit a single file. This does not seem to answer the problem - the question is about modifying a number of files (though it may not be obvious at first glance). If you know how to use ed for that purpose, show this in your answer. –  rozcietrzewiacz Sep 18 '11 at 2:38
    
@rozcietrzewiacz - Since grawity demonstrated the same method of editing a single file (that was accepted), I thought it was appropriate to the answer. Either way, I put it in a for loop, which should ease your concerns. –  Chris Down Sep 18 '11 at 12:21

An alternative to what you wrote for adding something to the end of every file in the directory (in bash):

for FNAME in *
do
    echo "?>" >> $FNAME
done

though I do like your find one-liner :)

share|improve this answer
    
$FNAME should be $fname -- by convention, we capitalize environment variables (PAGER, EDITOR, SHELL, ...) and internal shell variables (BASH_VERSION, RANDOM, ...). All other variable names should contain at least one lowercase letter. This convention avoids accidentally overriding environmental and internal variables. –  Chris Down Sep 18 '11 at 12:29
    
@Chris Down - the convention I have seen my entire career has varied by setting: lowercase, upper case, and camelcase :) –  warren Sep 19 '11 at 2:39
    
Camelcase and lowercase are fine. Either way, variables that are not environment variables should not be in full uppercase. –  Chris Down Sep 19 '11 at 2:41

There is the simple way

echo "startstr$(cat filename)endstring" > filename.new
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.