LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
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 11-15-2011, 08:21 PM   #1
SilversleevesX
Member
 
Registered: May 2009
Posts: 181
Blog Entries: 9

Rep: Reputation: 15
sed append string in variable to last line of file.


I know about this syntax, and I've seen it work.
Code:
sed '${s/$/atonic/}' file
(The last word on the last line of file was cat, in case you're curious.)

I'd like to know how, instead of using a literal string of text, to get a string stored in a variable to work.

Further down in that same file file, I added
Quote:
Complete this sentence for me:
"John Lennon once said, A man with his arm full of takeaways is either very hungry
And the variable, phrase, has this for a value
Quote:
or knows someone who's very hungry." Nigel Planer as Neil, THE YOUNG ONES.
Can this be done with sed, or should I look into doing it with awk or some other utility?

BZT

Last edited by SilversleevesX; 11-15-2011 at 08:29 PM.
 
Old 11-15-2011, 08:52 PM   #2
pcardout
Member
 
Registered: Jun 2003
Location: Socorro, New Mexico
Distribution: Debian ("jessie", "squeeze"), Linux Mint (Serena), XUbuntu
Posts: 221

Rep: Reputation: 24
Appending a string in a variable to a file

I suspect I have misunderstood your question. I do not use sed much, but I am pretty
comfortable with shell scripting. On the off chance you are missing the simple
stuff, here is a sample script

Code:
#!/bin/bash
var="What you want"
echo $var >> file.txt
cat file.txt
Every time you run this script it will append "What you want" to the end of your file.

Maybe you want to be fancier. Maybe you just want to append a word or phrase to a line in an existing file.
Then try this:

Code:
#!/bin/bash
line=$(tail -n 1 "file.txt")
stuff="Imagine"
echo $line $stuff >> file.txt
cat file.txt
The tail command picks up the last line of your file and sticks it in variable line. You can then use echo
to concatanate your new stuff.
 
1 members found this post helpful.
Old 11-16-2011, 01:40 AM   #3
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,999

Rep: Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190
Use double quotes with sed and any variables will be expanded.
 
1 members found this post helpful.
Old 11-16-2011, 10:19 AM   #4
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Grail has it right. Quotes and variables are processed by the shell before the command is launched. You simply need to make sure that the arguments are passed to it the way you want.

Take some time to learn how the shell processes arguments, whitespace, and quoting.
http://mywiki.wooledge.org/Arguments
http://mywiki.wooledge.org/WordSplitting
http://mywiki.wooledge.org/Quotes


Next, your specific example above requires a bit of work in order to store it properly in a variable, since it contains both a single and a double quote mark.

Probably the best way to handle that is to double-quote the whole string, and use a backslash to escape the double-quote inside it. The single quote is already escaped and doesn't pose a problem. Oh, and you'll probably want to include an initial space as well, to allow for a word-break in the final output.

Code:
ending=" or knows someone who's very hungry.\" Nigel Planer as Neil, THE YOUNG ONES."
Now just insert the variable into the command, and use double-quotes to allow it to expand.

(The brackets are unnecessary here, by the way. The first "$" is the address (last line) for the single "s" substitution command that follows it. You only need brackets when grouping or nesting commands.)

Code:
sed "$ s/$/$ending/" file
A good way to test what the final executed command will be is to try echoing it first:

Code:
$ echo sed "$ s/$/$ending/" file
sed $ s/$/ or knows someone who's very hungry." Nigel Planer as Neil, THE YOUNG ONES./ file
Remember that double-quoting the sed command also requires the same kind of care as when we set the variable. You may need to escape characters like $, \ and " as well, if they conflict with shell-reserved syntax. (Check out the quoting section of the bash man page for a full description of what double-quotes do and don't protect.
 
1 members found this post helpful.
Old 11-16-2011, 06:27 PM   #5
SilversleevesX
Member
 
Registered: May 2009
Posts: 181

Original Poster
Blog Entries: 9

Rep: Reputation: 15
Thanks to all three of you.

I tried the code and took the advice that David the H. posted and it does exactly what I was looking for.

I wasn't aware you could "echo" a sed as a way of viewing the results.

And now I'd like to share the reason for all this: I've been coming across some very good captions/descriptions in image files in my collection, and I was looking for a way to take these from "caption in a JPEG" to "caption below the picture on a Web page" without using any GUI apps. It occurred to me that I could use Exiv2 to get the caption, and as the value of a variable it could be placed between the appropriate HTML tags in an HTML file. The same is of course true for such things as width and height, file name (actual or "preferred," i.e., with or without the file extension) and other details appropriate to a simple gallery page. As scripts write these details in sequence, it's logical that the caption would be written to the page later. Still, as the caption or comment was one part that would very likely comprise the longest string of data to append to a file, I figured I would start with something very much like it before tackling the (likely) smaller bits. Kind of like the advice one gets on the order of "Do your math homework first," or "Eat your spinach before you eat the stuff you like" as one's coming up.

And that's the run of it.

BZT
pcardout: I fully intend to try the method you suggested, with tail and concatenated variables, some time soon.

Last edited by SilversleevesX; 11-16-2011 at 06:28 PM.
 
Old 11-17-2011, 08:30 AM   #6
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Sounds like a good start.

echo is simply a command like any other; its job is to print all the arguments that are passed to it, in order. This happens after the shell has processed the line, so what you see in the output are the same arguments that any command would receive. Whatever command you try, replace the actual command name with echo and you'll see the post-processed state of the arguments you used.


I haven't worked all that much with exif info, but I've found the perl-based exiftool to be much more flexible and powerful than exiv2. It allows for fine control over the output format.

You could do something like this with it:

Code:
#!/bin/bash

file="$1"

declare -A tags		# create an associative array to store the exif tags.
declare -l name		# also force the values stored in "name" to be lowercase, 
			# to make the array indexes easier to handle.
			# requires bash 4+

# loop through the exiftool output and create an array entry for each tag.
# uses the tag name as the array index.

while { IFS=$'\t' read name value ;} ; do
	tags[$name]=$value
done < <( exiftool -s -t "$file" )

# the exiftool -s and -t options print a tab-delimited output
# that's easy for read to deal with.

# now loop through and print out the values:

for name in "${!tags[@]}" ; do 
	echo "The value of '[$name]' is [${tags[$name]}]"
done

# or to echo some individual tags:

echo "File name: ${tags[filename]}"
echo "Image size: ${tags[imagesize]}"
echo "Comment: ${tags[comment]:-None}"
And if you want to print out code directly in html, you could build a pre-formatted template inside a here document.

Code:
cat <<TEMPLATE
<img src="${tags[directory]}/${tags[filename]}" height="${tags[imageheight]}" width="${tags[imagewidth]}" alt="${tags[comment]}" >
TEMPLATE
As a final suggestion, you may want to consider using functions to store all these commands in, to make the code cleaner and more structured.
 
1 members found this post helpful.
Old 11-27-2011, 11:01 PM   #7
SilversleevesX
Member
 
Registered: May 2009
Posts: 181

Original Poster
Blog Entries: 9

Rep: Reputation: 15
Quote:
Originally Posted by David the H. View Post
I haven't worked all that much with exif info, but I've found the perl-based exiftool to be much more flexible and powerful than exiv2. It allows for fine control over the output format.
I noticed that, too, and used it for something that one version of Exiv2 couldn't do.

Andreas Huggel, at the suggestion of myself and a few others who used Exiv2 strictly on the command line, introduced a "-g" option. As you might guess, it "grepped" the value of a tag, label or line in a file that, up until then, required one or more GNU greps to isolate.

In its first incarnation, it was flawed, as it only returned the first keyword of a file's keywords; likewise the first supplemental category. He's since extended the option's function to read in arrayed or multi-line values, but in the meantime, I found the command "exiftool -p formatfile foo.jpg" a reasonable alternative. I made two format files, one called 'jew' and the other 'gentile,' for keywords and supp. categories respectively, using commas as delimiters, and except that there were spaces between the commas and real data in the return to stout, it was a very decent workaround.

BZT

Last edited by SilversleevesX; 11-27-2011 at 11:08 PM.
 
Old 11-27-2011, 11:13 PM   #8
pcardout
Member
 
Registered: Jun 2003
Location: Socorro, New Mexico
Distribution: Debian ("jessie", "squeeze"), Linux Mint (Serena), XUbuntu
Posts: 221

Rep: Reputation: 24
Thanks for sharing the big picture w/ us SilversleevesX.

I complement you on your approach.
Command line work is the area where Linux shines and you can do all kinds of neat automation that the point and click crowd
cannot even imagine!
 
  


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
[SOLVED] append variable string in a specific line himu3118 Programming 4 06-08-2010 08:49 AM
Sed/awk/grep search for number string of variable length in text file Alexr Linux - Newbie 10 01-19-2010 01:34 PM
using sed to append a variable after a certain line jadeddog Programming 6 11-05-2008 12:49 AM
Append variable string(s) at end of each line schaganti Linux - Newbie 2 10-19-2007 01:31 PM
sed script to append variable text gmartin Linux - General 4 12-27-2006 04:44 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 04:34 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
Open Source Consulting | Domain Registration