LinuxQuestions.org
Go Job Hunting at the LQ Job Marketplace
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
LinkBack Search this Thread
Old 12-04-2008, 11:19 AM   #1
wtaicken
LQ Newbie
 
Registered: Dec 2008
Location: Dorset, UK
Distribution: Ubuntu 7.1
Posts: 25

Rep: Reputation: 15
Appending text to a series of files - advice


Hi, I'm trying to develop a script which will append a block of text to a series of text files in a number of directories. The appended text also has to have written within a line the relevant directory name. This could work by substituting for other text in the line.

I'm sure this is easy to do, but I'm struggling with the syntax for using sed within a script

Any assistance gratefully received

Will
 
Old 12-04-2008, 11:44 AM   #2
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: OpenSUSE 12.1 CentOS 6.2
Posts: 8,967

Rep: Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345
Hi and welcome to LQ! Just a thought: you have to establish a rule to list all the files you want to modify. Use the find command to list all these files, loop over them, extract the directory name using the dirname command and echo a string redirecting with >> (append). Pseudo-code:
Code:
for file in $(find blah blah blah)
do
  dir=$(dirname "$file")
  echo "This file is inside $dir" >> "$file"
done
Just pay attention to file names containing blank spaces. Anyway, show us what you've tried so far: it should be easier to get help.

Last edited by colucix; 12-04-2008 at 11:46 AM.
 
Old 12-04-2008, 12:31 PM   #3
wtaicken
LQ Newbie
 
Registered: Dec 2008
Location: Dorset, UK
Distribution: Ubuntu 7.1
Posts: 25

Original Poster
Rep: Reputation: 15
Hi Colucix

This is what I have generated so far, cobbled together from various sources on the web.......

I was experimenting by specifying a directory as an argument when calling the script, cd'ing to the directory, and then trying to append "input text" to the end of each file in the directory. But it was only appending the test text to the last file in the directory, and writing to the screen. How do I get it to append to all files and write to those original files?

if [ -z $1 ]; then
echo "Needs directory as argument."
exit 1
elif [ -f "$1" ]; then
dirname="$1"
fi
cd $1
list="$(ls ARCH*.dat)"
echo $list
for i in "$list";do sed '$a input text' $i; done
 
Old 12-04-2008, 02:31 PM   #4
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: OpenSUSE 12.1 CentOS 6.2
Posts: 8,967

Rep: Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345
Ok. I will correct your script and will suggest alternatives. A working version can be:
Code:
#!/bin/bash
if [ -z $1 ]; then
  echo "Needs directory as argument."
  exit 1
elif [ -d "$1" ]; then
  dirname="$1"
fi
cd $1
list="$(ls ARCH*.dat)"
echo $list
for i in $list
do
  sed -i '$a input text' $i
done
To test if $1 is a directory, use the -d test, not -f. The former checks if the name is a directory, the latter checks if the name is a regular file.

Moreover, when you embed $list in double quotes, the list of files is interpreted as a single string with file names separated by space (this is a side effect of the shell expansion). Hence the for loop is executed only once and the resulting sed command is something like:
Code:
sed '$a input text' ARCH1.dat ARCH2.dat ARCH3.dat ARCH4.dat ...
for this reason you append a string to the content of the last file only. Removing the double quotes gives the result you expect. You can also use the command substitution directly in the for loop, avoiding the assignment to the variable list:
Code:
for i in $(ls ARCH*.dat)
do
  sed -i '$a input text' $i
done
In addition, to actually modify the content of the file you have to use the -i option of sed.

The sed command is ok, since it appends (a) the string (input text) to the end ($) of the file. Indeed the special character $ in a sed command matches the last line in the file. However this works only if the file is not empty, that is if there is at least one line in the file.

To keep it simple you can use echo instead of sed
Code:
echo input text >> $i
This will echo the string and append it to the file. The double redirection (>>) means append.

Finally I suggest some good reading about shell scripting and sed (and also awk for future reference).
Bash Guide for beginners
Advanced Bash-Scripting Guide
Sed - An Introduction and Tutorial
Gawk: Effective AWK Programing
Have a nice scripting time!

Last edited by colucix; 12-04-2008 at 02:32 PM.
 
Old 12-05-2008, 05:19 AM   #5
wtaicken
LQ Newbie
 
Registered: Dec 2008
Location: Dorset, UK
Distribution: Ubuntu 7.1
Posts: 25

Original Poster
Rep: Reputation: 15
colucix
Hi again

Tried that, and yep it works a treat, cheers

Next step, trying to substitute some of the appended text for the dirname.
I've tried some of the online resources, but they don't have any specific examples

I basically want to change part of the appended text e.g. "nnnnn" for the dirname "$1" How can I do that in the body of the text to append? Tried the following which doesn't work:

#!/bin/bash

# script to append text to each file in a directory. The file wildcard & dir are specified # by user.


if [ -z $1 ]; then
echo "Needs directory as argument."
exit 1
elif [ -d "$1" ]; then
dirname="$1"
fi
cd $1
list="$(ls ARCH*.test)"
echo $list
for i in $list
do
sed -i '$a\
retrieve from ./REF_INTS/nnnn_testy.REFINT\
begin\
partial k-effective\
store as ./REF_INTS/nnnn_testy.REFINT\
begin' $i | sed -i 's/nnnn/"$1"/'
done
 
Old 12-05-2008, 06:03 AM   #6
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: OpenSUSE 12.1 CentOS 6.2
Posts: 8,967

Rep: Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345
You can insert a command substitution in the sed command using quotes like this:
Code:
sed -i '$a\
retrieve from ./REF_INTS/'$(command_here)'_testy.REFINT\
begin\
partial k-effective\
store as ./REF_INTS/nnnn_testy.REFINT\
begin' $i
That is you close the single quote, put the command substitution $(...) and re-open the single quotes to terminate the sed command. The command can be dirname $i or better readlink -f $i, but it depends on the result you want to obtain. I'm afraid that if you use dirname, the result will be always the current directory "." (dot) since you change to the directory at the beginning of the script and build the list of files that haven't got the path in their name.
 
Old 12-05-2008, 06:48 AM   #7
wtaicken
LQ Newbie
 
Registered: Dec 2008
Location: Dorset, UK
Distribution: Ubuntu 7.1
Posts: 25

Original Poster
Rep: Reputation: 15
Ok, will try that.

BTW, how do you insert code inside the box in the message? Obviously a neater way of creating the post
 
Old 12-05-2008, 06:53 AM   #8
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: OpenSUSE 12.1 CentOS 6.2
Posts: 8,967

Rep: Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345Reputation: 1345
Of course. If you go to advanced mode (see the "Go Advanced" button at the bottom of the Quick Reply box, below) you can simply highlight some text and press the hash (#) button. Or explicitly put CODE tags around the text. For example if you write

[CODE]#!/bin/bash
echo Hello World\![/CODE]

it will result in
Code:
#!/bin/bash
echo Hello World\!
 
Old 12-05-2008, 07:02 AM   #9
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,695
Blog Entries: 5

Rep: Reputation: 237Reputation: 237Reputation: 237
Quote:
Originally Posted by colucix View Post
Code:
for i in $(ls ARCH*.dat)
do
  sed -i '$a input text' $i
done
no need for ls
Code:
for i in ARCH*.dat
do
 ...
done
another:
Code:
sed -i '$a input text' ARCH*.dat
 
Old 12-08-2008, 04:58 AM   #10
wtaicken
LQ Newbie
 
Registered: Dec 2008
Location: Dorset, UK
Distribution: Ubuntu 7.1
Posts: 25

Original Poster
Rep: Reputation: 15
Ok, thanks
I now find I need to substitute another character in the text to append. I need to read through the original input file ($i), and search for the last occurrence of a word from a look up list. Once that word is found, I need to take the last number from the line where the word occurs, and substitute that for the character "x" in the text to append.

I guess I should now use grep?

I also need to extract a character from the file name, and substitute that for a character "y" in the text to append.

E.g The filename will be something like *****_test2_*****. I need to extract the "2" from the name. Guess that can be done in a similar way?

Guess I should now do the appending last, after modifying the text to append
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Need help appending text to lines in a file using vi editor tmbrwolf53 Linux - Newbie 3 10-31-2008 03:25 PM
sed - appending text 7stud Linux - Newbie 2 03-01-2007 02:10 PM
Appending to a certain line in text w3stfa11 Programming 5 11-09-2006 09:33 AM
Appending Text Files From Bash Script alts Programming 3 11-18-2004 06:36 PM
PHP appending form fields and text. BigFred Programming 6 09-19-2003 10:02 AM


All times are GMT -5. The time now is 01:11 PM.

Main Menu
 
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: @linuxquestions
Open Source Consulting | Domain Registration