LinuxQuestions.org
Latest LQ Deal: Complete CCNA, CCNP & Red Hat Certification Training Bundle
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 04-01-2011, 01:14 PM   #1
jr950
LQ Newbie
 
Registered: Apr 2011
Posts: 9

Rep: Reputation: 0
appending to the current line in a file instead of creating a new line


Hi; this is a very basic question, I think:

I am combining data from a couple different input files and creating an output file in a specific format.

I notice that if I use the >> operator, information gets appended to a new line in my output file.

This is useful, but if I'd like to append onto the CURRENT line, is there an easy way to do this? I've been googling around and see lots of complicated answers, nothing that suggests to me an easy way to do this.

For example, if my output file looks like this:
b1a:] cat test
hello my name is
b1a:]

and I'd simply like to append "Bob", how can I do it? If I use
b1a:] echo Bob >> test
b1a:] cat test
b1a:] hello my name is
Bob
b1a:]

So what I would prefer is some command that would create the result:

hello my name is Bob


any ideas?

Thanks!
 
Old 04-01-2011, 01:59 PM   #2
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
No, regular redirection won't work here. You need either some fancier scripting or an external tool. Try sed:
Code:
sed -i '$ s/.*/& Bob/' file
-i option edits the original file directly
$ matches the last line of the file
s/// replaces the first with the second string
.* matches the whole line
& inserts the matched pattern into the replacement string
Don't forget the space between them!
 
Old 04-01-2011, 02:10 PM   #3
crts
Senior Member
 
Registered: Jan 2010
Posts: 1,606

Rep: Reputation: 448Reputation: 448Reputation: 448Reputation: 448Reputation: 448
Hi,

if you simply want to append at the end of the last line then David's solution can be even shortened to just:
Code:
sed -i '$ s/$/ Bob/' file
 
Old 04-01-2011, 02:32 PM   #4
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
Thanks crts. I should've thought of that.

$ in this case means "end of line", so just replace it with the desired string.

Here's a bash-only version I just thought of, assuming the file is of a reasonable size.
Code:
f="$(<file.txt)" ; echo "${f%$'\n'} Bob" >file.txt
f="$(<file.txt)" imports the whole file into a variable.
echo "${f%$'\n'} Bob" removes the final newline*, if it exists, and tacks on your replacement text.
>file.txt overwrites the original file with your replacement.

* This is an example of parameter substitution and the $'..' extended quoting pattern, which expands backslashed special characters like \n "newline" into their literal ascii characters. It requires the extquote shell option to be enabled, but this is the default.
 
Old 04-01-2011, 02:59 PM   #5
jr950
LQ Newbie
 
Registered: Apr 2011
Posts: 9

Original Poster
Rep: Reputation: 0
Wow, thanks for the solution - works very well, thank you!
 
Old 04-01-2011, 04:36 PM   #6
jr950
LQ Newbie
 
Registered: Apr 2011
Posts: 9

Original Poster
Rep: Reputation: 0
Actually, the solution
sed -i '$ s/$/ Bob/' file
still leaves me in a bit of a quandary.

This is great if the text to append is a static string like Bob. But if the text I'd like to append on the current line comes from another variable, let's say $appendThis, it breaks down.

For example

b1a:] echo Hello my name is > newFile
b1a:] cat newFile
Hello my name is
b1a:] appendThis=Bob
b1a:] sed -i '$ s/$/ $appendThis/' newFile
b1a:] cat newFile
Hello my name is $appendThis


of course, I'd like the contents of newFile to contain
Hello my name is Bob
and not
Hello my name is $appendThis.

Any ideas?

Thanks!

Last edited by jr950; 04-01-2011 at 04:38 PM.
 
Old 04-01-2011, 04:45 PM   #7
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
The single quotes around the sed command prevent the shell's variable substitution. Until there are not special characters whose expansion is permitted inside double quotes, you can try:
Code:
sed "$ s/$/ $append/" file
Remember that "using double quotes the literal value of all characters enclosed is preserved, except for the dollar sign, the backticks (backward single quotes, ``) and the backslash" (from the Bash Guide for Beginners). In this case the dollar signs in the sed address and in the regular expression are not expanded, since they are not associated to something recognizable by the shell. The first $ is followed by a blank space, the second one is followed by / and these combinations have not special meanings for the shell.

Last edited by colucix; 04-01-2011 at 04:50 PM. Reason: Added information
 
Old 04-01-2011, 04:48 PM   #8
jr950
LQ Newbie
 
Registered: Apr 2011
Posts: 9

Original Poster
Rep: Reputation: 0
Yep, that did the trick. Thanks!
 
Old 04-02-2011, 05:03 PM   #9
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
Also be aware of possible conflicts with sed's delimiters. If the phrase you're trying to replace contains any / characters, it will break the command.

You can avoid this by using a less common delimiter. Sed can accept any single-byte ascii character as a delimiter, so instead of s/x/y/, you can use s|x|y|, or s^x^y^, etc. Just choose one that's unlikely to exist in your input string.

(see man 7 ascii for a full list of ascii characters).

Or use the bash code I gave you instead. It doesn't suffer this kind of problem.

Last edited by David the H.; 04-02-2011 at 05:04 PM. Reason: highlighting
 
Old 04-08-2011, 04:06 PM   #10
jr950
LQ Newbie
 
Registered: Apr 2011
Posts: 9

Original Poster
Rep: Reputation: 0
Guess I speak too soon on some occasions.

@colucix: your solution actually prints the desired output to the screen rather than appending to the fire as desired. It also seems to insert an undesired space between the newly appended string and the text originally on the line.

@David the H: your solution (very nearly) works. It appends the text, but it also inserts an undesired space (I checked both the original text and the text to be appended, and neither contained either a leading or trailing space; the space was inserted upon appending). Also, my ouput file will grow to be quite large. Don't know yet if this will become a problem yet, as I haven't run it on real data yet.

Thanks?
 
Old 04-08-2011, 04:25 PM   #11
jr950
LQ Newbie
 
Registered: Apr 2011
Posts: 9

Original Poster
Rep: Reputation: 0
There is an additional problem with @David the H's bash-only version. If I'd previously inserted a newline so that when I append to the file, I'd expect the appended text to be appended to the new line, the command given deletes newlines that I'd previously intentionally added.

Here's a full example

b1a] fileName=file.txt
b1a] echo HelloMyNameIs > $fileName
b1a] cat $fileName
HelloMyNameIs
b1a] echo >> $fileName
b1a] cat $fileName
HelloMyNameIs

b1a] appendThis=Bob
b1a] f="$(<$fileName)" ; echo "${f%$'\n'} $appendThis" >$fileName
b1a] cat $fileName
HelloMyNameIs Bob

In this case, I'd like the resulting file to contain text that looks like this:
cat $fileName
HelloMyNameIs
Bob

Any ideas welcome!
 
Old 04-08-2011, 05:01 PM   #12
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
Quote:
Originally Posted by jr950 View Post
@colucix: your solution actually prints the desired output to the screen rather than appending to the fire as desired. It also seems to insert an undesired space between the newly appended string and the text originally on the line.
You don't really think I could give you a command that actually modifies the content of the file without testing it?!? To actually change the file content use the -i option of sed. Regarding the extra space, I cannot see where does it come from. Please, can you post a real example?
 
Old 04-08-2011, 05:09 PM   #13
jr950
LQ Newbie
 
Registered: Apr 2011
Posts: 9

Original Poster
Rep: Reputation: 0
@colucix: I posted a real example just above your post (see today, #11). Just replace the line:

f="$(<$fileName)" ; echo "${f%$'\n'} $appendThis" >$fileName

with a different idea!
 
Old 04-08-2011, 05:21 PM   #14
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
Pardon me but still I cannot see what is the undesired space you mentioned. Here is my example:
Code:
$ cat newFile
Hello my name is
$ append=Bob
$ echo $append
Bob
$ sed "$ s/$/ $append/" newFile
Hello my name is Bob
in this case I intentionally put a space to separate words. Otherwise I would get:
Code:
sed "$ s/$/$append/" newFile
Hello my name isBob
 
Old 04-08-2011, 05:28 PM   #15
jr950
LQ Newbie
 
Registered: Apr 2011
Posts: 9

Original Poster
Rep: Reputation: 0
Hi @colucix. Using the -i flag and removing the space, the solution works. Thanks.

I also found a result within an old posting in a similar thread; answer provided by Zulfilee:

http://www.linuxquestions.org/questi...4/#post2299440

Thanks.
 
  


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



Similar Threads
Thread Thread Starter Forum Replies Last Post
Command for appending a text at the start of every line and save it another file ssgupta Linux - Newbie 5 03-10-2011 09:35 AM
shell script- appending line by line metis Programming 5 06-21-2010 11:53 PM
need to write a shell script for appending text into each line of a file nandakv4 Programming 9 08-15-2009 04:32 AM
C++ Line Comparisons and Appending in another file vk10 Programming 3 09-26-2008 08:50 PM
appending line at the last line of a file .. vks_agra Linux - General 13 06-20-2006 08:51 PM


All times are GMT -5. The time now is 09:47 AM.

Main Menu
Advertisement
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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration