LinuxQuestions.org
Help answer threads with 0 replies.
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
  Search this Thread
Old 05-30-2011, 06:03 PM   #1
pawn
LQ Newbie
 
Registered: May 2011
Posts: 3

Rep: Reputation: Disabled
here-document with parameter as limitstring


Hello,
I'm trying to write a program, that will take a parameter as the limit string for a here-document.
Also, I want to output any document as the here-document.
For example i want to say:
./hereProgram document.txt EOF
where the first parameter is the file and the second the limitstring.
I'm facing two problems here.
First, when using a parameter as the limitstring, the end is not recognized:
hereProgram.txt:
Code:
cat <<"$@"
Line 1
Line 2
EOF
calling this with:
./hereProgram EOF
will fail because EOF is not the same as $@. this however works:
hereProgram.txt:
cat <<"$@"
Line 1
Line 2
$@

The second problem is, that theres always input expected after calling cat <<EOF. So i can place some text after the command, but not insert a file. This will work
Code:
cat <<EOF
Line 1
EOF
however this will not
Code:
cat <<EOF
cat document.txt
here EOF is located in document.txt.

I hope you can help me with either problem.
thanks a lot

Last edited by pawn; 05-30-2011 at 07:00 PM.
 
Old 05-30-2011, 06:40 PM   #2
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
First of all, please use [code][/code] tags around your code, to preserve formatting and to improve readability.

A here string has a very specific design and syntax, and I don't think it's subject to parameter expansion. The whole point of it is to separate out a block of text in the current shell, after all.

For example, your second code example works because it's using the literal delimiting string "$@", not replacing it with the actual parameter.

Also, the ending delimiter must always start at the beginning of a line, with no spaces in front of it. Some shells may allow certain things to follow it, but it's not defined behavior, so the only safe thing is to place it alone on a line.

It seems to be possible to do this using eval though.
Code:
#!/bin/bash

eval cat <<$1

"some stuff"

$1

exit 0
This appears to work with simple here strings at least. I haven't yet figured out if there's any way to quote the delimiter string this way though. Putting some escaped quotes around it doesn't seem to work.
 
Old 05-30-2011, 07:28 PM   #3
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
Originally Posted by pawn View Post
Hello,
I'm trying to write a program, that will take a parameter as the limit string for a here-document.
Also, I want to output any document as the here-document.
For example i want to say:
./hereProgram document.txt EOF
where the first parameter is the file and the second the limitstring.
I recommend awk instead of a shell script for this.
Code:
awk -v end="EOF" 'BEGIN { RS="(\r\n|\n\r|\r|\n)" ; RT="\n"; FS="[\t\v\f ]+" }
                  (NF==1 && $1==end) { exit(0); }
                  { printf("%s%s", $0, RT) }' document.txt
If you use GNU awk, it will retain the newline convention used in the file; other awks will convert the newline convention to UNIX newlines (LF or "\n" only). The end pattern must be the only thing on that line, but it can be indented with whitespace. You can use any string or parameter instead of EOF, as long as it does not contain newlines (LF "\n" or CR "\r"). (For all command line parameters, use $* and not $@, so that it is considered a single string and not split into multiple command line parameters. For arrays, use ${variable[*]} and not ${variable[@]} for the same reason.)

This awk script first sets RS, the record separator (newline); RT, the default output record separator (GNU awk will always reset it to whatever was used for that record); and FS, field separator (so that the end string can be indented).
If there is only one field on a line, and it matches the end string, the script exits.
Otherwise the record is printed (using the original newline if supported, default newline otherwise).

As awk streams the input files, it only keeps about one record worth of data (or a few kilobytes, whichever is greater) in RAM at a time. It is therefore pretty efficient. It is much faster than using a shell script, too.
I suspect the eval example shown by David the H. reads the entire file into RAM first.
 
Old 05-30-2011, 08:38 PM   #4
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,005

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
I am curious as to why the need for a different delimiter for the here document? (or did I miss something?)
The word used is of no particular importance and as far as I know is not able to be used as a reference point elsewhere in your code.

As for redirecting a file into a here document:
Code:
cat <<EOF
$(< file_name)
EOF
 
1 members found this post helpful.
Old 05-31-2011, 01:55 AM   #5
pawn
LQ Newbie
 
Registered: May 2011
Posts: 3

Original Poster
Rep: Reputation: Disabled
this is actually part of a task we've been given at school. And since the program has to run in any shell, unfortunately it's not possible to do it with awk. thank you anyway for the suggestion.
right now i'm thinking of building the whole command as a simple string and then just evaluating it afterwards. i'll keep you updated.
thanks
 
Old 05-31-2011, 05:23 AM   #6
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by pawn View Post
this is actually part of a task we've been given at school
Can you post the relevant part of the task specification?
 
Old 05-31-2011, 09:53 AM   #7
pawn
LQ Newbie
 
Registered: May 2011
Posts: 3

Original Poster
Rep: Reputation: Disabled
as it turns out, i didn't read the problem very thoroughly, as was pointed out to me today.
it says to build a program, that will act "like" cat <<EOF with a variable parameter for the limitstring.
so i don't actually have to use an actual here document. All i'm gonna do now is to read every line from a text file and check against the limitstring.
that aside, i'm really surprised about all those fast and devoted answers.
thank you very much
 
  


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
looking for i915 parameter document or Is i915 good for N10? kaz2100 Debian 6 07-10-2011 06:17 PM
shell getopts: opt w/ optional parameter is taking next opt as its parameter! GrapefruiTgirl Programming 22 10-27-2010 06:00 AM
html; character encoding per document tag, not whole document TheLinuxDuck Programming 0 08-14-2008 11:12 AM
linux bash - how to use a dynamic parameter in shell parameter expansion expression nickleus Linux - General 2 08-21-2006 04:54 AM
Convert openoffice document into ms document through cli? bruno buys Linux - Software 0 07-05-2004 09:59 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:26 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