LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   wanna to add in newlines in begin and end of multiple files (https://www.linuxquestions.org/questions/linux-newbie-8/wanna-to-add-in-newlines-in-begin-and-end-of-multiple-files-708122/)

tiaratiara 02-27-2009 09:42 PM

wanna to add in newlines in begin and end of multiple files
 
I wish to add in one line before the end of file and add in two lines in the beginning of files. I tried this to add in the line before the end of file. But the output is weird.

#!/bin/bash
j=1
for i in *.html; do
if [[ $j -lt 13 ]]; then
echo \n "</DOC>/" >>cc_${j}.html
j=$(($j+1));

done

It looks like </DOC>/ would be following the last line.But what I want is make </DOC>/ the last line.

Anyone knows the mistakes of my code?

Also, Could I add in lines in front of and in the end of files in the same time? Would this cause errors?

Thanks

bgoodr 02-28-2009 10:44 AM

Use the sed, Luke
 
Quote:

Originally Posted by tiaratiara (Post 3460061)
I wish to add in one line before the end of file and add in two lines in the beginning of files.

You will be better served in the future to learn to use sed (do a man
sed) for text editing, and not bash, since it is more efficient. The
syntax may take a bit of head scratching, but is well worth it. Here
is an example:

Code:

#!/bin/sh

# Just write out some sample input to sed (you can pipe input into sed as you see fit instead):
cat > /tmp/inputfile <<EOF
line 1
line 2
line 3
line 4
EOF

# We can put the "<file" operator at the front of the command too (a
# little awkward for some folks):

< /tmp/inputfile sed '
# This line is a comment. Please use them so you avoid confusion later.
# Blank lines are ok too, and sometimes make things easier to read:

# The "i" command "i"nserts before the line given to the left of it.
# $ means the last line. If you change the "i" to an "a" it will
# append it _after_ the line. So this next command inserts two lines
# in the front of line 1. Notice the backslashes at the end of the "a
# line at the front" line, which is necessary to tell sed that another
# line is to be inserted as well:
1i\
a line at the front\
and another line at the front

# The "i" command "i"nserts before the line given to the left of it.
# $ means the last line. If you change the "i" to an "a" it will
# append it _after_ the line:
$iAn extra line right _before_ the last line\
And another line right after it.

# You did not ask for this, but here is a way to match a regular expression "line 2"
# and do something silly with it:
/line 2/ablubber butts need exercise (right after line 2)
'

Good Luck!
bgoodr

tiaratiara 03-13-2009 04:38 PM

Occurs error when I try out....
 
Since I need do this for a series of files, I tried
####################################
#!/bin/bash
j=1

for i in *.html; do
if [[ $j -lt 13 ]]; then
cat > T_1_${j}.html <<EOF;
line 1
line 2
line 3
line 4

< T_1_${j}.html sed '
1i\
<DOC>\
<DOCNO>yichu_chen_1_${j}</DOCNO>


$i</DOC>\
fi
j=$(($j+1))
done
######################################
But errors occurs that syntax error: unexpected end of file
and sometimes I also got problems like unexpected EOF while looking for matching `''
can't figure out what kind of mistakes I made.....

rysiekmus2 03-13-2009 05:01 PM

sed
 
Hi,

I had a similar problem with sed and an XML file with tags like "<text>". Unexpected end of file, I don't know what it was, I only know that I could only use VI, using the same expression as in sed - worked. Must be something with the tags, or the way the file is terminated.

Regards,
Richard

bgoodr 03-14-2009 10:38 AM

Quote:

Originally Posted by tiaratiara (Post 3474756)
Since I need do this for a series of files, I tried
<snip>
But errors occurs that syntax error: unexpected end of file
and sometimes I also got problems like unexpected EOF while looking for matching `''
can't figure out what kind of mistakes I made.....


I believe that you have two syntax errors: The first is that you didn't terminate the here-document expression that starts with:
Code:

cat > T_1_${j}.html <<EOF;
The here-document is of this general form:
Code:

some_command <<XYZ
some lines that do not have XYZ all by itself on a line
with no whitespace at the beginning or end.
and note that "XYZ" is a token that does not have special characters in it like
semicolons or whitespace.  Here comes the terminating line
XYZ

For example:
Code:

cat >/tmp/somefile1 <<E1
this line goes into /tmp/somefile1
this extra line also goes into /tmp/somefile1
E1

echo This output does not go into any file
echo but instead goes out to standard output
echo of the script when it is executed

cat >/tmp/somefile2 <<E2
this line goes into /tmp/somefile2
this extra line also goes into /tmp/somefile2
E2

The second syntax error is the multi-line sed script is not terminated with a single quote (see "OOPS" comment below):
Code:

< T_1_${j}.html sed '
1i\
<DOC>\
<DOCNO>yichu_chen_1_${j}</DOCNO>


$i</DOC>\
' # <--- OOPS
fi
j=$(($j+1))
done

Also, since the ${j} expression is in the single-quoted block, it won't get expanded by bash (note that sed knows nothing of that variable since $j is a bash variable and not a sed variable). But, the single-quotes are ok, it is the part of the variable reference itself that needs to be tweaked. So, replace:
Code:

${j}
with
Code:

'"${j}"'
(even though the double-quotes are not necessary in this specific case, since $j will most likely _not_ have whitespace in it, it is a good habit to put them in because maybe later you change your mind and want a filename that can have spaces in it.)

So after my hacking on your script, I ended up with this:
Code:

#!/bin/bash

j=1
max_files=3

while [ $j -le $max_files ]; do
    file="T_1_${j}.html"
    echo Generating file $file ...
    cat > $file <<EOF
line 1
line 2
line 3
line 4
EOF
    echo Processing file $file ...
    < $file sed '
1i\
<DOC>\
<DOCNO>yichu_chen_1_'"${j}"'</DOCNO>


$i</DOC>\
'
    j=$(($j+1))
done

Enjoy!
bg

tiaratiara 03-17-2009 08:29 PM

Hi,
I tried to fixed my code based on your suggestion.Your code is more like create new files and write in new lines in front of and in the end of it. However, I need to perform this to some existing files and their names can't be specific right now.(I used specific name is because I want to try out the code.) So, I think I don't need the cat part and just do the sed part.
But somehow the change would appear in the terminal windows but would not write into the files.And I still can't figure out how to operate files when I don't know their names so I just tried the belowed code.
The T_1_1 to T_1_7 are existing files.

#!/bin/bash
j=1
for i in *.html; do
if [[ $j -lt 7 ]]; then

< T_1_${j}.html sed '
1i\
<DOC>\
<DOCNO>T_1_'"${j}"'</DOCNO>


$i</DOC>\
'

fi
j=$(($j+1));

done

bgoodr 03-17-2009 11:45 PM

Quote:

Originally Posted by tiaratiara (Post 3478857)
Hi,
I tried to fixed my code based on your suggestion.Your code is more like create new files and write in new lines in front of and in the end of it. However, I need to perform this to some existing files and their names can't be specific right now.(I used specific name is because I want to try out the code.) So, I think I don't need the cat part and just do the sed part.
But somehow the change would appear in the terminal windows but would not write into the files.And I still can't figure out how to operate files when I don't know their names so I just tried the belowed code.
The T_1_1 to T_1_7 are existing files.

Code:

#!/bin/bash
j=1
for i in *.html; do
if [[ $j -lt 7 ]]; then

 < T_1_${j}.html  sed '
1i\
<DOC>\
<DOCNO>T_1_'"${j}"'</DOCNO>


$i</DOC>\

 
fi
j=$(($j+1));

done


You are almost home free. Compare the above script with:

Code:

#!/bin/bash

# Just create some sample files (this won't be in your final script of course):
cat > T_1_flubber.html <<EOF
flubber line1
flubber line2
flubber line3
EOF

cat > T_1_bozo.html <<EOF
bozo line1
bozo line2
bozo line3
EOF

cat > T_1_bugsbunny.html <<EOF
bugsbunny line1
bugsbunny line2
bugsbunny line3
EOF

# Now for the part that actually does the editing:
for file in T_1_*.html
do
    # Just using a fragment of the file instead of numbers to
    # illustrate pulling out pieces of text using echo and sed
    # commands. The real power here is in the regular expression in
    # the sed s%%%g command, where the % character is the separator. A
    # lot of folks use / as the separator, which is fine, but often
    # you are dealing with filepaths that have slashes, and putting
    # backslashes in front of the slashes is ugly:
    fragment=$(echo "$file" | sed 's%^T_1_\([^.]*\)\.html$%\1%g')
    #    echo "fragment==\"${fragment}\""
    # Notice the redirection into a temporary file which I've faked
    # here using the $$ variable which is the process id of the
    # current script:
    < "$file" > tmpfile.$$  sed '
1i\
<DOC>\
<DOCNO>T_1_'"${fragment}"'</DOCNO>


$i</DOC>\

    mv tmpfile.$$ "$file"
    cat "$file"
done

Hey: Please do us all a favor and add "code" tags around your code and
indent it consistently (yeah, I know that sed sections can't be
indented).

bg

schneidz 03-17-2009 11:51 PM

does
Code:

echo; echo; cat file.txt; echo
get you what you want ?

bgoodr 03-18-2009 09:32 PM

Yep!


All times are GMT -5. The time now is 04:22 PM.