Bookmark and Share

Adding new lines to beginning of files.

Posted: Tuesday, May 5th, 2009 at 8:58 pmUpdated: Tuesday, May 5th, 2009 at 8:58 pm

I needed to do this when I want to debug my scripts for memory usage. My problem at that time was that as I include libraries, for some reasons PHP uses more memory even though I haven’t run a single code (other than require_once).

So my idea is to add memory_get_usage() function call on the beginning of each files. Moreover, that function call should appear in the beginning of a file.

This, apparently poses some problems. Some searches on Google found no real solutions to a quick howto in appending line(s) to the beginning of a file. Many of them have ways to append to the end of file, which is already built-in in Unix-like (read Linux, MacOS X, FreeBSD, etc) operating system. In case you don’t know, use >> operator to append a line to a file. For example, to add new line to the end of existing file test.txt,

user@dev:~/work$ echo “new line” >> test.txt

 

What we are working towards

Rather than giving bogus / made-up example, I thought I’d post what exactly I needed. As you recall, I need to add memory_get_usage() function call to the beginning of file. Ideally the output of that function call is

  • Saved to some log file so it’s easy for me to look at.
  • Includes the file name so I know what file is the culprit.
  • For easier to read, display the memory in megabytes instead of bytes.

Having considered all the above requirements, here’s the PHP script I came up with.

error_log(
	__FILE__ . " "
		. number_format(memory_get_usage(true) / (1024 * 1024), 2)
		. " MBn",
	3,
	"/tmp/script_memory_usage"
);

Save the following script as some temporary file. I named it as jajal.sh.

sed '1i<?php error_log(__FILE__ . " " . \
number_format(memory_get_usage(true) / (1024 * 1024), 2) . \
" MBn", 3, "/tmp/vas2"); ?>' $1 > /tmp/jajal.php && \
mv /tmp/jajal.php $1

Then find all PHP codes to append.

user@dev:~/work$ find . -type f -name “*.php” -exec ./jajal.sh {} ;

Alternatively, you can also use for loop built-in with the shell. This way, you don’t really need to have temporary shell script (that jajal.sh script above)

user@dev:~/work$ for i in `find . -type f -name “*.php”`;
do
sed ‘1i<?php error_log(__FILE__ . ” ” . number_format(memory_get_usage(true) / (1024 * 1024), 2) . ” MBn”, 3, “/tmp/vas2”); ?>’ $i > /tmp/jajal.php && mv /tmp/jajal.php $i
done

The above works on Linux. If you’re working on other OS, you may need to modify your sed command like below:

user@dev:~/work$ for i in `find . -type f -name “*.php”`;
do
sed ‘
quote> 1i\
quote> <?php error_log(__FILE__ . ” ” . number_format(memory_get_usage(true) / (1024 * 1024), 2) . ” MBn”, 3, “/tmp/vas2”); ?>
quote> ‘ $i > /tmp/jajal.php && mv /tmp/jajal.php $i

Just for completeness sake … we may want to revert what we did above. So below is the counterpart; to delete the first line from specified files.

user@dev:~/work$ for i in `find . -type f -name “*.php”`; do sed ‘1 d’ $i > /tmp/jajal.php && mv /tmp/jajal.php $i; done

There you have it. And as always, I welcome comments / questions / critics that will help me and other readers understand better.

Leave a Reply