LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   How to remove first 2 lines of a file in a script (http://www.linuxquestions.org/questions/programming-9/how-to-remove-first-2-lines-of-a-file-in-a-script-526606/)

nazs 02-07-2007 10:57 PM

How to remove first 2 lines of a file in a script
 
Hi All,
I have a file that is ftp'd each night. The file needs to have the first 2 lines deleted before being sent via ftp. How do I put that into the script? It needs to open the file,remove first two lines and then save the file with the lines removed.

Thanks,
Nazs

nadroj 02-07-2007 11:28 PM

Code:

#!/bin/csh

set file = $1

cp $file $file.tmp

@ num = `cat $file | wc -l` - 2

tail -$num $file.tmp > $file

rm $file.tmp

just a quick and simple script with no error checking, etc.. but seems to do what you want. maybe instead of renaming the file to $file.tmp make it $file.tmpX, where X is some variable.. such as the date, and get rid of the rm command. so you always have a backup of each one

hope this helps.

matthewg42 02-07-2007 11:28 PM

Code:

sed -n -i '3,$ p' filename

nadroj 02-07-2007 11:29 PM

..or that!

kshkid 02-07-2007 11:49 PM

Code:

awk '{ if( NR > 2 ) { print } }' currentfile > newfile

nazs 02-08-2007 12:02 AM

Thank you all for the quick responses. I still have some questions. Each file that is created has a counter. The file will always start with 2351 and then has a counter after that. The script looks for 2351*.OUT . So it might be 2351AA.OUT. The next one would be 2351AB.OUT and so on. For now i was trying the sed -n -i '3,$ p' filename which i put in bold and red. So i am not sure what to put down for the file name after sed -n -i '3,$ p' filename. Here is my script below.


#!/bin/sh

UNIDUMP=/usr/pa/universe/unidump/
ARCHIVE=/usr/pa/universe/unidump/bin_uni/archive/
LOG=/var/tmp/unisend.log

cd $UNIDUMP

#CHECK IF THERE ARE ANY FILES
gunzip $UNIDUMP/2351*.OUT.gz

if [ `find . -type f -maxdepth 1 -name "2351*.OUT*" | wc -l` -eq 0 ]; then
echo "Exit NO FILES"
exit
else

COUNTER=`find . -type f -maxdepth 1 -name "2351*.OUT"`

for i in $COUNTER;do
sed -n -i '3,$ p' filename

echo "record removed"

su slp -c "/usr/bin/gpg --no-tty -vsear AOB --passphrase-fd 0 $i< ~lsp/.gnupg/pw"


# FTP FILE TO AOB


Thanks again,
Nazs

matthewg42 02-08-2007 12:22 AM

Please post code in [code] tags to improve readability.

No need to assign the list of files to a variable and then use it. Use xargs:

Code:

...
find . -type f -maxdepth 1 -name "2351*.OUT" | xargs sed -n -i '3,$ p'

...that assuming you wish to rmove the first two lines of all the files which find identifies.

nazs 02-08-2007 12:47 AM

I am getting this error:

sed: invalid option -- i
Usage: sed [OPTION]... {script-only-if-no-other-script} [input-file]...

-n, --quiet, --silent
suppress automatic printing of pattern space
-e script, --expression=script
add the script to the commands to be executed
-f script-file, --file=script-file
add the contents of script-file to the commands to be executed
--help display this help and exit
-V, --version output version information and exit

If no -e, --expression, -f, or --file option is given, then the first
non-option argument is taken as the sed script to interpret. All
remaining arguments are names of input files; if no input files are
specified, then the standard input is read.

E-mail bug reports to: bug-gnu-utils@gnu.org .
Be sure to include the word ``sed'' somewhere in the ``Subject:'' field.

Nazs

matthewg42 02-08-2007 03:01 AM

What do you get from this command:
Code:

sed --version

kshkid 02-08-2007 03:38 AM

the sed version OP is using should probably be
Code:

GNU -- 3.02

matthewg42 02-08-2007 04:40 AM

Wow, that's quite old. The version I have is 4.1.5. You can use a temporary file instead of the -i option (which says to edit a file in-place):
Code:

find . -type f -maxdepth 1 -name "2351*.OUT" | while read file; do
    sed -n '3,$ p' "$file" > "$file.new"
    mv "$file.new" "$file"
done


makyo 02-08-2007 06:29 AM

Hi.

Here is an alternative to sed for skipping the first 2 lines of a file, namely by using tail:
Code:

#!/bin/sh

# @(#) s1      Demonstrate tail copying from beginning.

rm -f t1 t2
seq 100 >t1
L1=$( cat t1 | wc -l )
echo
echo " File t1 is $L1 lines long."

tail +3 t1 > t2
echo
L2=$( cat t2 | wc -l )
echo " File t2 is $L2 lines long."

echo
echo " Here are the first 10 lines of t2:"
head -10 t2

When run, this produces:
Code:

% ./s1

 File t1 is 100 lines long.

 File t2 is 98 lines long.

 Here are the first 10 lines of t2:
3
4
5
6
7
8
9
10
11
12

Best wishes ... cheers, makyo

( edit 1: typo )

matthewg42 02-08-2007 10:49 AM

You could also do it with ed. This command will work so long as your echo command supports the -e option (expand \ escaped characters). This is another nice one in that it doesn't create a second file - it modifies in-place:
Code:

echo -e "1,2 d\nw" | ed file
...or if your echo command doesn't, you might try it like this (which is a little more portable to some older and/or non-GNU systems):
Code:

(echo "1,2 d" ; echo "wq")| ed file
Again, you'd wrap this up in a loop as I described with the second sed examples (not the xargs one).

nazs 02-08-2007 10:07 PM

I just want to thank everyone for helping me. Mathewg42 this is what worked for me:

echo -e "1,2 d\nw" | ed file

Thanks alot!

Nazs

cfaj 02-18-2007 10:34 PM

Quote:

Originally Posted by nazs
Thank you all for the quick responses. I still have some questions. Each file that is created has a counter. The file will always start with 2351 and then has a counter after that. The script looks for 2351*.OUT . So it might be 2351AA.OUT. The next one would be 2351AB.OUT and so on. For now i was trying the sed -n -i '3,$ p' filename which i put in bold and red. So i am not sure what to put down for the file name after sed -n -i '3,$ p' filename. Here is my script below.


#!/bin/sh

UNIDUMP=/usr/pa/universe/unidump/
ARCHIVE=/usr/pa/universe/unidump/bin_uni/archive/
LOG=/var/tmp/unisend.log

cd $UNIDUMP

#CHECK IF THERE ARE ANY FILES
gunzip $UNIDUMP/2351*.OUT.gz

if [ `find . -type f -maxdepth 1 -name "2351*.OUT*" | wc -l` -eq 0 ]; then
echo "Exit NO FILES"
exit
else

COUNTER=`find . -type f -maxdepth 1 -name "2351*.OUT"`

for i in $COUNTER;do
sed -n -i '3,$ p' filename

echo "record removed"

su slp -c "/usr/bin/gpg --no-tty -vsear AOB --passphrase-fd 0 $i< ~lsp/.gnupg/pw"

You don't need to check whether there are any files:

Code:

for i in 2351*.OUT
do
  {
    read; read; cat
  } < "$i" > TEMP
  mv TEMP "$i"
done



All times are GMT -5. The time now is 08:00 AM.