Bash - Appending to specific line in file


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Bash - Appending to specific line in file
# 1  
Old 04-11-2013
Bash - Appending to specific line in file

I'm working on a personal project, a multiplication quiz script for my kids. In it, the user's performance will be recorded and written to a file. After they've played it a little while, it will start to focus more on the ones that give them the most trouble-- that take a long time to answer or that they more frequently get wrong.

The information for each user will be written out to a file for future reference. The format will be something like:

Code:
factor1,factor2|trial1|trial2|...|trialn

where each trialx will look like:

Code:
YES/NO,answer_given,time_to_answer

YES/NO is simply the answer to the question, "Did the user give the right answer?" So, long explanation over... Here's what I'm wondering: What is the best way to append the most recent results to particular lines? Suppose that the user chooses to do a 3-question test and gets this output:
Code:
3,6|YES,18,1.635
9,10|YES,90,1.838
8,6|NO,47,4.510

Then I want to take "YES,18,1.635" and append it to the "3,6" line of the file. Similarly, "YES,90,1.838" will be appended to the "9,10" line, and so on. What's your suggestion for the best way to do this from within a script? I can load the external file into an array, append, and write out, for example, but is that the best way? How would you do this? Please let me know if the question is unclear. Many thanks in advance.
# 2  
Old 04-11-2013
Assumed your filename is "file".
With sed:
Code:
factor="3,6"
trial="YES,18,1.635"
sed '/'"$factor"'|/ s/$/|'"$trial"'/' < file > file.new

With the shell built-ins it becomes a bit long,
so a function makes sense:
Code:
append () {
IFS="|"   
while read factor trial
do
  if [ "$factor" = "$1" ] 
  then
    echo "$factor|$trial|$2"
  else
    echo "$factor|$trial"
  fi
done < file > file.new
}

and call it
Code:
append "3,6" "YES,18,1.635"

---------- Post updated at 02:47 PM ---------- Previous update was at 02:38 PM ----------

The sed version has the problem that it does not have a true field separator.
Here is an awk version:
Code:
awk -F"|" '{if ($1==factor) {print $0 FS trial} else {print}}' factor="3,6" trial="YES,18,1.635" < file > file.new

This User Gave Thanks to MadeInGermany For This Post:
# 3  
Old 04-11-2013
Quote:
Originally Posted by MadeInGermany
Assumed your filename is "file".
With sed:
Code:
factor="3,6"
trial="YES,18,1.635"
sed '/'"$factor"'|/ s/$/|'"$trial"'/' < file > file.new

With the shell built-ins it becomes a bit long,
so a function makes sense:
Code:
append () {
IFS="|"   
while read factor trial
do
  if [ "$factor" = "$1" ] 
  then
    echo "$factor|$trial|$2"
  else
    echo "$factor|$trial"
  fi
done < file > file.new
}

and call it
Code:
append "3,6" "YES,18,1.635"

---------- Post updated at 02:47 PM ---------- Previous update was at 02:38 PM ----------

The sed version has the problem that it does not have a true field separator.
Here is an awk version:
Code:
awk -F"|" '{if ($1==factor) {print $0 FS trial} else {print}}' factor="3,6" trial="YES,18,1.635" < file > file.new

Unfortunately, both of these examples only work if all possible values of factor are in file before you try to add a new trial. If you want to start with an empty file and add new entries (as well as update existing entries), you could try these minor updates:
Code:
append () {
IFS="|"
found=0
while read factor trial
do
  if [ "$factor" = "$1" ] 
  then
    echo "$factor|$trial|$2"
    found=1
  else
    echo "$factor|$trial"
  fi
done < file > file.new
if [ $found = 0 ]
then
    echo "$1|$2" >> file.new
fi
}

Code:
awk -F"|" '{if ($1==factor) {print $0 FS trial;found=1} else {print}END{if(! found) print factor FS trial}' factor="3,6" trial="YES,18,1.635" < file > file.new

This User Gave Thanks to Don Cragun For This Post:
# 4  
Old 04-22-2013
Thank you for both replies. I apologize for not responding sooner and for bumping a thread so long after it was replied to. A family emergency prevented (or, at least distracted from) replying sooner. The suggestions are now being turned into a working solution.

One question, though... Since the separator of choice, "|", follows both the factors at the beginning of the line and each of the subsequent trial entries, wouldn't only one existent trial be preserved from the file? Suppose there's a line:

8,6|NO,47,6.110|NO,47,3.910

Wouldn't $factor be "8,6" and $trial be "NO,47,6.110", the first trial? It seems like the second would be discarded and no more than 2 trials would ever be preserved. But I could easily be reading wrong. If not, though, perhaps I would be better off with a file structure like:

Code:
factor1,factor2|trial1|trial2|...|trialn

and IFS=":". What think ye? Again, many thanks.

Last edited by treesloth; 04-22-2013 at 08:36 PM..
# 5  
Old 04-23-2013
I apologize. In my last posting, the awk program I supplied was missing a closing brace. I should have pasted it in the form I used when I tested it instead of converting it back to a 1-liner. Try the following awk script (but use /usr/xpg4/bin/awk, /usr/xpg6/bin/awk, or nawk instead of awk if you're using a Solaris/SunOS system):
Code:
awk -F"|" '
{       if($1==factor) {
                print $0 FS trial
                found=1
        } else print
}
END{    if(! found) print factor FS trial
}' factor="3,6" trial="YES,18,1.635" < file > file.new

And, no. Changing the field separator from "|" to ":" will not make any real difference. This script will add new trial results to the line in file that has the given factors (or add a new line if the given factors are not already in file); not replace existing trial results. It will never replace existing trial information when adding a new trial. You just need to move or copy file.new to file after each trial is successfully added.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Appending content of a file to another file before a specific character

Hi there, i've got a file with this content $ cat file1 Matt Mar The other file has the same number of lines with this content: $ cat file2 20404=767294 23450=32427 is there a way with either using sed, awk or paste to insert the content of file1 before the "=" character? So... (3 Replies)
Discussion started by: nms
3 Replies

2. Shell Programming and Scripting

Extract specific line in an html file starting and ending with specific pattern to a text file

Hi This is my first post and I'm just a beginner. So please be nice to me. I have a couple of html files where a pattern beginning with "http://www.site.com" and ending with "/resource.dat" is present on every 241st line. How do I extract this to a new text file? I have tried sed -n 241,241p... (13 Replies)
Discussion started by: dejavo
13 Replies

3. UNIX for Advanced & Expert Users

Appending a files contents to the end of a specific file name in several directories

Here is my dir structure: /tmp/dave/myappend.txt /tmp/dave/dir1/test.txt /tmp/dave/dir2/test.txt /tmp/dave/dir3/test.txt /tmp/dave/dir4/test.txt I want to append the contents of myappend.txt to the end of each file with the name "test.txt" in all dirs in /tmp/dave/ I have tried this:... (2 Replies)
Discussion started by: bigd213
2 Replies

4. UNIX for Dummies Questions & Answers

Comparing to specific line in file bash script

Hi, I have a value stored in x and I need to compare it to the numbers in every other line of a file. The file contains alternating lines of numbers and letters: aaaa1111 AAAAAAAA bbbb2222 BBBBBBBB cccc3333 CCCCCCCC I need to compare x to the numbers in every other line without the... (2 Replies)
Discussion started by: ShiGua
2 Replies

5. UNIX for Advanced & Expert Users

Appending # to the start of specific line in a properties file

Hi, I have the following file, ABC.txt: ABC=123 DEF=234 FGH=345 Based on my validation and conditional processing it is observed that i need to comment or append # before DEF=234 so the same file ABC.txt should look as follows ABC=123 #DEF=234 FGH=345 Sorry if its a... (6 Replies)
Discussion started by: mihirvora16
6 Replies

6. UNIX Desktop Questions & Answers

Appending file extensions to filenames in bash scripts

Hi Suppose I have a variable called filename and it it contains the name of a file. I then would like to append an extension to that filename. The filename currently has no extensions. How do I do this? Thanks (11 Replies)
Discussion started by: ladyAnne
11 Replies

7. Shell Programming and Scripting

How to read the value from a specific line and column BASH

Hi All, I have the same problem as the one posted in https://www.unix.com/shell-programming-scripting/96097-how-read-value-specific-line-column-csh-variable.html but I'm using bash. Can anyone tell me how I have to modify the code to make it bash compatible? eval `awk 'NR==3{print "set... (5 Replies)
Discussion started by: f_o_555
5 Replies

8. Shell Programming and Scripting

Appending a column in one file to the corresponding line in a second

It appears that this has been asked and answered in similar fashions previously, but I am still unsure how to approach this. I have two files containing user information: fileA ttim:/home/ttim:Tiny Tim:632 ppinto:/home/ppinto:Pam Pinto:633 fileB ttim:xkfgjkd*&#^jhdfh... (3 Replies)
Discussion started by: suzannef
3 Replies

9. Shell Programming and Scripting

Appending the line number and a seperator to each line of a file ?

Hi, I am a newb as far as shell scripting and SED goes so bear with me on this one. I want to basically append to each line in a file a delimiter character and the line's line number e.g Change the file from :- aaaaaa bbbbbb cccccc to:- aaaaaa;1 bbbbbb;2 cccccc;3 I have worked... (4 Replies)
Discussion started by: pjcwhite
4 Replies

10. Shell Programming and Scripting

Reading specific contents from a file and appending it to another file

Hi, I need to write a shell script (ksh) to read contents starting at a specific location from one file and append the contents at specific location in another file. Please find below the contents of the source file that I need to read the contents from, File 1 -----# more... (5 Replies)
Discussion started by: dnicky
5 Replies
Login or Register to Ask a Question