sed help

I think I’ve written my first awk script with help of course! :slight_smile:

set cmd to "echo 'aadsheughauh
kwevswyebes' | awk '
BEGIN { print \"START\" }
      { print NR, \".	\", $0 }
END   { print \"STOP\"  }
do shell script cmd

Had to make a guess with the $0.

Edited: added the period “.”.


Well done kel.

I urge you to have a look at man printf, printf is a command you can use almost everywhere, at least in the shell, in awk, and when programming in C.

I have taken liberties with your effort, and used printf instead:

set cmd to "echo 'Anticipate what the user needs.
Stick to the topic.
Check your answer, if it is correct.
Do not diverge with side-topics, at least not before the user gotten  a correct answer.
Give an answer the user understands.
Do not  be intimidating.
Be polite, even if the user is arrogant.
Try to write correct english.
Format your code with bbcoding.
Follow up the thread to see if the user has feedback.' | awk '
BEGIN { printf \"10 Commandments for helping users\\n\\n\" }
{ printf \"%d. %s\\n\",NR, $0 }
do shell script cmd

I have another link for you, for learning awk, not saying it is any better, just as an alternative. It is just as bad or good as the grymoire, but it implements some techinques that may be interesting. Steve’s Awk Academy.

Hi McUsr,

I look into printf. It looks like print with format.

The tutorial looks very easy to follow.

Thanks a lot,


Awk is also a primitive tool, the primary purpose is to create reports from text files. But it is not more primitive than that you can create a relational database with it.

Sed is good at extracting and substituting data, awk is good at decorating the data. It worked that fast, because I used the sed-constructs of it in the post above, it slows down significantly when you start using loop constructs and variables.

Sometimes, if you loop over files and doesn’t use text manipulation capabilities, (perfectly easy to do you do have a “system-like” call in awk, as in python), then bash may be the correct place to implement the solution.

I’d say FileMaker Pro is much more suited for that, (or 4D if you can afford it, (pun intended)).

he he he and I updated the script above, to contain the 10 reply commandments, given the talk about the bible and all that. :wink:


And I don’t think every aspect of printf is easy, there are a lot of detail there, but the basics is that %d represents a signed integer, %s a string, \t a tab, and \n a newline, and that covers for the most basic usage. You will want to use spaces whenever you can instead of tabs, to assure correct output.

I’ll be back with an example later, I couldn’t make it work right now.



I am sorry for not mentioning that a space is what that is supposed to delimit the two fields.

This is the original table:

Here is a script to produce tables like this:

It is not perfect, you’ll have to adjust a little, for some reason. I guess the hard spaces (opt-shft space) are translated to tabs by bbcode, when there are sufficiently many of them, you’ll just have to insert one in the first line above to make it perfect.

like this:

set tids to AppleScript's text item delimiters
set a to the clipboard
set theRes to paragraphs 1 thru -2 of (do shell script "tr '
' '
' <<< " & quoted form of a & " |tr -s ' ' |tr '.' ',' |awk 'BEGIN {IFS = \" \"} {printf \"%15s %4.2f\\n\",$1,$2}' ")
repeat with apar in theRes
	set AppleScript's text item delimiters to " "
	set tmptext to text items of apar
	set AppleScript's text item delimiters to " "
	set contents of apar to tmptext as text
end repeat
set AppleScript's text item delimiters to linefeed
set the clipboard to theRes as text
set AppleScript's text item delimiters to tids

So now it should be easy to make good looking tables, just put the two columns into a text edit document, copy it
eventually tweak the format string a little, paste it in between quote tags in a post, look, adjust, and there you are! :slight_smile:

The page has been revamped recently and I suspect this slipped past the editorial eye. I don’t remember now if there was a one-sed line-numbering demo in the original or not. But here are three primitive attempts of my own. None is ideal as the numbers have to be written into the scripts, so the number of lines must be less than or equal to the number for which has been catered. These three scripts can handle a maximum of ten lines per text:

set cmd to "<~/Desktop/WolfandCrane.txt  sed '
# Number each line explicitly (!)
1 s/^.*$/1.'$'\\t''&/
2 s/^.*$/2.'$'\\t''&/
3 s/^.*$/3.'$'\\t''&/
4 s/^.*$/4.'$'\\t''&/
5 s/^.*$/5.'$'\\t''&/
6 s/^.*$/6.'$'\\t''&/
7 s/^.*$/7.'$'\\t''&/
8 s/^.*$/8.'$'\\t''&/
9 s/^.*$/9.'$'\\t''&/
10 s/^.*$/10.'$'\\t''&/
do shell script cmd
set cmd to "<~/Desktop/WolfandCrane.txt  sed -E '
1 {
	# Copy the first line of text to the hold space, replace the pattern space copy with a reversed row of line numbers and dots, swap the line with the numbers.
# Append each line in turn to the end of the numbers, get a copy of the result.
# Delete the last number, dot, and line text from the copy and swap with the original.
# Preserve only the last number and dot, a tab, and the line text in the original (and print them).
do shell script cmd
set cmd to "<~/Desktop/WolfandCrane.txt  sed -En '
# Collect copies of all the lines into the hold space.
1 h
1 !H
$ {
	# Replace the original of the last line with a reversed row of numbers and dots, append that to the hold space too, get everything back into the pattern space.
	# Repeatedly move the number and dot at the end of the text, along with a tab, to the beginning.
	# Print up to the first linefeed.
	# Delete up to and including the first linefeed.
	# Repeat while any linefeeds remain.
	/\\n/ b loop
do shell script cmd

An interesting exercise, but not particularly useful!

I agree the effort and skill however, are impressive! :slight_smile: But since we are talking about counting here, it is fully possible to append a character to the hold buffer for each time you want to perform an iteration, togehter with the t instruction, you can then later on iterate the number of times.

I hope this made sense, as I can’t reproduce it in the moment.

Each time an event occur in a sed script, you swap the hold and pattern space. (the holdspace is then unusable for other purposes), you substitute the patternspace which now are the holdspace, so that it becomes one character longer. then you swap back. (x)
later on, when the first stage of processing is done, then you repeat the sequence, but now you subsitute so that the patternspace become 1 character less, after the substitution, you use the ‘t’ instruction, to branch above to where your iteration starts, so that you can bail out or jump to another label if there are no more iterations left (the t instruction fails.)

As I sed, I hope it made sense. :slight_smile:

Hi McUsr,

Thanks for the starters with Awk. I can see how ‘printf’ is better right off the bat. ‘print’ automatically adds a newline and placing the formatting at the beginning (i.e. %d and %s) must allow less typing for each printed item.

I can’t get your last script to work without error yet, but I will be working on it. I think i’d rather place the tabs between the fields as a delimiter, instead of at the beginning of the line. Here’s my first test script:

-- tabs separate fields
set t to quoted form of "hello	1
goodbye	2
morning	3"
set cmd to "echo " & t & " | awk '
BEGIN { printf \"Start\\n\" }
printf \"%d\\n\",$2
END { printf \"Finish\" }'"
do shell script cmd

Testing the bb for how tabs work in the quotes:

Thanks a lot,

It seems that tabs don’t work well in the quotes. But, they work well in text editors.

Hello it isn’t better in any way, it is different, but some jobs are suited for sed, other for awk, and some are best suited not using any of them. It all depends on the problem. It is only fast, when you use it as you would use sed, with regards to the flow of a script, that it uses patterns and clauses for the different patterns as you would structure a sed script. There is one exception, and that is when you are using associative arrays.

And I am sorry about the tabs, I figured a space would be best after all. I forgot to mention that I guess. :confused:


The table script is work in progress, I’ll come back at a later time with something far more usable. :wink:

Hi Nigel and McUsr,

I didn’t see your posts after my last post. Didn’t know we were on page 2 already.

I don’t remember if Bruce Barnett had written the one invocation solution neither. Yes it doesn’t make much sense if you can’t use the line numbering command ‘=’.

I just thought of something. You can get the number of lines. No, that won’t work, because you would need to invoke sed again to reenter the lines. There always seems to be a catch with this puzzle. It’s like Fermat’s last theorem. :slight_smile:

Will be looking into your script later, Nigel. I have to maybe fix my flat tire or I might wait until tomorrow and use my backup car.


Fermat’s last theorem got solved, getting the linenumbers, an arbitrary number by one invocation of sed, is unsolvable (just sed, nothing else), as long as you don’t cheat and write your own version of sed, that handles it. :slight_smile:


:smiley: I am not going to write a formal proof, but there are indeed just two memory locations, that are available, and they are not even available at exactly the same time.

To count line numbers, you’ll need at least one place to hold the variable, and you need some facility to increment a counter of sorts (which sed lacks), for this you’ll need one extra memory location, to keep what you are adding into a register, some constant register would have served, but there are no such facility in sed. And there, we were out of resources, for incrementing a line number in sed with one invocation of it, while retaining, and putting the line number into the pattern space before printing the line. Simple as that, there is no puzzle to be solved here.

Mayve you can do it with sed in a bash here document, but we do have nl, that creates a line-numbered stream, and it does that perfectly well.

Fermat’s Last Theorem is solved! Now I really feel like Rip Van Wrinkle. :smiley:

I see what you’re saying. You trade speed and simplicity for other options. To everything, there is a purpose.

Have a good day,

Yeah. That is the tool-theory, a tool should do one thing and do it well, and you’d choose the right tool for the job.

This is a good approach, as long as the tool-chain is fast enough, and only then do you rewrite in a higher level language, you can also view tools as functional objects. That using tool is indeed object oriented, sort of.

here is the Wikipedia article about Fermat’s last theorem

I also think you’d like to have a look at the Chinese remainder theorem as well; the calculation is the proof.
If you detested it at school, you may find it intriguing now!

And you have a good day as well kel. -Always a pleasure!


Here is a free book for you: Aho/Ullman: Foundations of Computer Science


In 1995, amazing:

Where have you been??? :slight_smile:

Just kidding, but I remember it as it was today. I was reading it in internet explorer, on Windows 95, I had an annoying friend at the time, who had a Mac, to every problem I had he just said, why don’t you just do it like that, or Ah, I just do that to accompish it. :slight_smile: AppleTalk and sharing documents. No such thing on Windows 95!

The book about Fermat’s last theorem, is by the way a very good one, with lots of interesting math in it.

Actually, I got too obsessive with computers in the past. So, I had to go fishing, or hiking, or gardening, or guitars or etc. When I get too obsessive, I go cold turkey. Then, I know that I don’t have to do something all the time. Computers can be addicting. Who would ignore another brain. :slight_smile:

Edited: forgot golf. :smiley:

I would lie if said I didn’t know what you were talking about. :wink:

Things got much easier after I started having laptops, less to carry around. :smiley:

By the way, if there is too much sunshine outside, there is a keyboard shortcut: ctrl-opt-cmd 8, that inverts the screen!

It works most of the time.