LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
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 04-17-2010, 04:36 PM   #16
webhope
Member
 
Registered: Apr 2010
Posts: 184

Original Poster
Rep: Reputation: 30

Quote:
Originally Posted by colucix View Post
The sed command works for me. Please, can you post a "not working" example? What is the value of $line in that case?
AWK. Not sed. You answered yourself in the following text:

Last edited by webhope; 04-18-2010 at 11:51 AM.
 
Old 04-18-2010, 05:46 AM   #17
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Would I be correct in assuming that there is only ever, at most, one # on a line?
If so:
Code:
awk -F# '{if(NF > 1)print $2;else print "#"$0}'
 
Old 04-18-2010, 05:50 AM   #18
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Quote:
Originally Posted by grail View Post
Would I be correct in assuming that there is only ever, at most, one # on a line?
If so:
Code:
awk -F# '{if(NF > 1)print $2;else print "#"$0}'
Nice trick!
 
Old 04-18-2010, 11:53 AM   #19
webhope
Member
 
Registered: Apr 2010
Posts: 184

Original Poster
Rep: Reputation: 30
I have finished with this code:

Code:
# VIEW LINE
line=$(echo $line | sed '/[[:space:]]*#/b1; s/^/#/; b2; :1; s/[[:space:]]*#//; :2'  );
echo $line;

# SAVE TO FILE $0
echo $line | sed -i -e '/[[:space:]]*#/b1; s/^/#/; b2; :1; s/[[:space:]]*#//; :2' $script
Maybe it is possible to run it only as one command (save and print output)?

Quote:
Originally Posted by grail View Post
Would I be correct in assuming that there is only ever, at most, one # on a line?
Sometimes I comment this:

urpmi -auto program # install my program
# urpmi -auto program2 # not install my program2

Last edited by webhope; 04-18-2010 at 11:56 AM.
 
Old 04-18-2010, 09:12 PM   #20
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
No probs:
Code:
awk -F# '{if($1 == "")print $2;else print "#"$1}'
 
Old 04-19-2010, 03:13 AM   #21
webhope
Member
 
Registered: Apr 2010
Posts: 184

Original Poster
Rep: Reputation: 30
I found a problem when I tested write to file. The code:

Code:
count=$( echo "$content[@]"  | wc -l );
clear; OLDIFS=$IFS; IFS=$'\n';

select line in $content; do 
line=$(echo $line | sed '/[[:space:]]*#/b1; s/^/#/; b2; :1; s/[[:space:]]*#//; :2'  );
echo $line;

# SAVE
echo $line | sed -i  '/[[:space:]]*#/b1; s/^/#/; b2; :1; s/[[:space:]]*#//; :2' $script
if [[ "$LINE" == "${content[$count]}" ]]; then exit; fi;
done;
or without -e

It switches all comments to no comments and all no comments to comments. So the target script does't work at all. What I do wrong? When we test the command to print on output everything works.

Edit:
Is it the problem:
Should I keep original $line. And to create $new_line by sed? Echo $new_line. Then use sed command to change $line to $new_line in $file?

This code works for me:

Code:
content=$content$'\E[1;33m\nFinish\E[1;0m';
count=$( echo "$content[@]"  | wc -l );

clear; echo -e $'\E[1;33m''Choose a line:'$'\E[1;0m'; OLDIFS=$IFS; IFS=$'\n';

select line in $content; do 

# NEW LINE + ECHO
new_line=$(echo $line | sed '/[[:space:]]*#/b1; s/^/#/; b2; :1; s/[[:space:]]*#//; :2'  );
echo $new_line;

if [[ "$line" == "${content[$count]}" ]]; then exit; 
else
# SAVE
line=${line//\//\\\/};
sed -i -e "s%$line%$new_line%" $script
fi;

done;
Test it too.

One more problem in the script. The finish option doesn't work - condition and ${content[$count]} array not accessed correctly

Error:
++ [[ Finish == '' ]]

Last edited by webhope; 04-19-2010 at 03:52 AM.
 
Old 04-19-2010, 08:27 AM   #22
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
So i seem to be getting more confused, but hey, that happens. I am curious why all the extra steps??
If I am understanding correctly, see above for confused, then the content is an array??
I will continue on this assumption:
Code:
content[${#content[*]}]=$'\E[1;33m\nFinish\E[1;0m'

clear; echo -e $'\E[1;33m''Choose a line:'$'\E[1;0m'

select line in $content
do
    if [[ "$line" == "Finish" ]]
    then
        break
    else
        line=$(echo "$line" | awk -F# '{if($1 == "")print $2;else print "#"$1}')
        echo "$line" > $script
    fi
done
Something I noted on one of the bash tutorials too is:
Quote:
Note that select uses the $PS3 prompt (#? ) by default, but this may be changed.
So maybe change:
Code:
echo -e $'\E[1;33m''Choose a line:'$'\E[1;0m'
to
PS3=$'\E[1;33m''Choose a line:'$'\E[1;0m'
 
Old 04-19-2010, 09:56 AM   #23
webhope
Member
 
Registered: Apr 2010
Posts: 184

Original Poster
Rep: Reputation: 30
Grail,
why are you confused. Content is content of a file $0 or $script. Thats the same. $0 is the file that is running.

I think about content like an array.

Code:
count=$( echo "$content[@]"  | wc -l );
Because it counts the lines.

After setting
Code:
IFS=$'\n';
select line in $content;
Select takes it like array.

But in real it is not array. But if IFS is '\n' then command
${content[10]} should access line 10.

Watch this block of my function how it works:

Code:
job=("Uninstall not needed" $'\E[1;33mSources\E[1;0m' $'\E[1;35mCodecs\E[1;0m' $'\E[1;32mNeeded\E[1;0m' "Finish");
select choose in "${job[@]}"; do
    case $chosse in
      ${job[0]}) step="1"; uninstall $SYSTEM; break;;
      ${job[1]}) step="2"; addmedia $SYSTEM; break;;
      ${job[2]}) step="3"; codecs $SYSTEM; break;;
      ${job[3]}) step="4"; done="0"; continue=1; break;;
      ${job[4]}) done="0"; break;; # this is the FINISH
    esac;
    done;
done;
This works perfectly. Job here is a simple array.

Thanx you solved my old question I use PS3="?:" for select now.

The last thing to resolve is the condition, that makes different between exit code and edit command:

Code:
if [[ "$line" == "${content[$count]}" ]]; then exit;  # EXIT
else
# SAVE
line=${line//\//\\\/};
sed -i -e "s%$line%$new_line%" $script
fi;
Could it be possible to get content[$count] behave like an array?

You are right. We can use
Code:
if [[ "$line" == "Finish" ]]
But I am used to work with the select dynamically. That means I don't insert concrete value. See the "select choose" with the "job" array above.

In the case command:
Code:
${job[4]}) done="0"; break;; # this is the FINISH
job[4] for behaves like array (and for the example above it works perfectly).

If I want to simulate the situation for if condition
we would have e.g. job[53] or job[content] or job[$content] or something like this. I don't know why this doesn't work if select can work with it as like with array.

Last edited by webhope; 04-19-2010 at 11:45 AM.
 
Old 04-19-2010, 02:55 PM   #24
webhope
Member
 
Registered: Apr 2010
Posts: 184

Original Poster
Rep: Reputation: 30
I try your command

I try your if command

This works:

Code:
[ "Finish" == "Finish" ] && echo OK
++ '[' Konec == Konec ']'

But this not

Code:
[ "$line" == "Finish" ] && echo OK
++ '[' 'Finish' == Finish ']'

Same as

Code:
if [ "$line" == "Finish" ];
The line is:
Code:
$'\E[1;33m\nFinish\E[1;0m'
That is the reason why I wanted do it by dynamical access as array.
I don't know why debug mode shows:
++ '[' 'Finish' == Finish ']'

like line there is not escape sequence.

Last edited by webhope; 04-19-2010 at 03:14 PM.
 
Old 04-19-2010, 07:27 PM   #25
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Yes I found that out after I added all the colorizing
Not to fear, was an easy(ish) fix:
Code:
content[${#content[*]}]=$'\E[1;33m\nFinish\E[1;0m'

clear; PS3=$'\E[1;33m''Choose a line:'$'\E[m'

select line in ${content[@]}
do
    if [[ "$line" == "${content[${#content[*]}-1]}" ]]
    then
        break
    else
        line=$(echo "$line" | awk -F# '{if($1 ~ /^[ \t]*$/)print $2;else print "#"$1}')
        echo "$line" >> $script
    fi
done

Last edited by grail; 04-19-2010 at 08:20 PM.
 
Old 04-19-2010, 08:20 PM   #26
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Just in case you wanted a different way:
Code:
output=x
script=$1 #or where ever you get this from

while [[ "x$output" != "x" ]]
do
    awk '{print NR") "$0}END{print (NR+1)") Finish"}' $script
    read -p $'\e[1;33mChoose a line: \e[m' choice

    output=$(awk -F# 'NR == '"$choice"'{if($1 ~ /^[ \t]*$/)print $2;else print "#"$1}' $script)
    [[ ! -z "$output" ]] && echo "$output" >> $new_script
    echo
done
 
Old 04-20-2010, 01:57 AM   #27
webhope
Member
 
Registered: Apr 2010
Posts: 184

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by grail View Post
Yes I found that out after I added all the colorizing
Not to fear, was an easy(ish) fix
Are you sure your code works?

My output:

Code:
 94) lives                 198) urpmi
 95) urpmi                 199) --auto
 96) --auto                200) htmldoc
 97) kdenlive              201) urpmi
 98) urpmi                 202) --auto
 99) --auto                203) ksayit
100) pitivi                204) urpmi
101) #                     205) --auto
102) Není                  206) xsel
103) ve                    207)
104) zdrojích              208) Finish
Choose a line:
1) It parsed word by word.
2) 208 to exit does not work
3) If I take if condition from your code and give it to my code, it does nothing. In the right part of it I see many escape sequences, letter by letter escaped. Maybe it is normal, but - this should be the problem. Maybe the test interprets the right part incorrectly. Maybe he needs some commands. Maybe we have different bash versions.

I have:
GNU bash, version 4.0.33(2)-release (i586-mandriva-linux-gnu)

Did you read what I wrote - I think the basic problem is this:

Code:
[ "$line" == "Finish" ] && pause
Debug putput is different:

Code:
'[' 'Finish' == Finish ']'
That means the problem is in interpreting $line.

Line should ocntent something like this:
Code:
line=$'\E[1;33m\nKonec\E[1;0m';
This is code which we should get from the script by awk.

But in real, here is something strange. If I use the select - choose Finish - then when debuging I don't see yellow color text of the Finish text. While if I use this command:

Code:
set -x
line=$'\E[1;33m\nKonec\E[1;0m'; # WARNING: this is not same as the line we get from awk!
[ "$line" == "Konec" ] && echo "OK"
1) I see yellow text in output
2) I see breakline in output!

This is output:

Code:
+ line='
Konec'
That could mean:
there is difference what we have got from awk and what we get by your command - trying to access the content as a array[index-1]

I would say that content got by
Code:
array[index-1]
has the \n on end of line and yellow formatting, which need not to be seen while debugging test command (?)

If so, can you just to change last line of the content to remove this two things?

Last edited by webhope; 04-20-2010 at 02:22 AM.
 
Old 04-20-2010, 02:27 AM   #28
webhope
Member
 
Registered: Apr 2010
Posts: 184

Original Poster
Rep: Reputation: 30
I hope you read my actual post changed at 9:22 AM. Not mail post that is older.
 
Old 04-20-2010, 09:02 AM   #29
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Ok, we seem to be at odds here. I was of the understanding that you were handling the putting
of the data into your array "content", hence you would need to set the IFS=$'\n' which would then affect
the select the same way and not break it up into 208 pieces.

Yes i saw your earlier post about $line == "Finish" hence why it has been changed in
post #25 to:
Code:
if [[ "$line" == "${content[${#content[*]}-1]}" ]]
This then takes into account that it is not just "Finish", but also the extra coloring which needs to be taken
into query.

All of this has worked for me.

The awk version in post #26 (which may obviously not be where you wish to go) does not require any of this testing
as the while loop handles the fact that choosing the number for "Finish" will result in an empty string from the final awk
statement.

Ok .... just ran post #25 against the following file:
Code:
urpmi --auto iqnotes
urpmi --auto htmldoc
#urpmi --auto ksayit
urpmi --auto xsel
I did also notice that you had added (which I mistakenly copied from your "Finish" item and not the one I had) a "\n"
which was causing issues, so the following (including the creation of array);
Code:
#!/bin/bash

IFS=$'\n'
content=($(cat "$1"))
content[${#content[*]}]=$'\E[1;32mFinish\E[1;0m'

clear; PS3=$'\E[1;33mChoose a line: \E[m'

select line in ${content[@]}
do
    if [[ "$line" == "${content[${#content[*]}-1]}" ]]
    then
        break
    else
        line=$(echo "$line" | awk -F# '{if($1 ~ /^[ \t]*$/)print $2;else print "#"$1}')
        echo "$line" >> script.out
    fi
done
When run above file, produced the script.out file which I entered the following number combination - 1 3 5
[/CODE]
#urpmi --auto iqnotes
urpmi --auto ksayit
[/CODE]

I also ran script from post #26 on same file with same choices to receive the same output.

Note: The select in script one just presents a new prompt each time but does not refresh the list whereas the awk script does.
Not sure which is better
 
Old 04-20-2010, 09:37 AM   #30
webhope
Member
 
Registered: Apr 2010
Posts: 184

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by grail View Post

Yes i saw your earlier post about $line == "Finish" hence why it has been changed in
post #25 to:
Code:
if [[ "$line" == "${content[${#content[*]}-1]}" ]]
I think that you came with this (red color text) code as 1st one... If I remember right. Was it misunderstanding? I don't search back. Maybe just because I have in my script such testing block [ "$line" == "Konec" ] && echo "OK" - that doesn't work. It is simplified form for debugging. But the target is still to do a dynamical command.

( Wait I will continue ... )

I will need to leave and come back at the night.

I checked your last code and it works for me. But I need to check it again to understand what does it do.

( Wait I will continue ... )

Actually I am not sure what does this
Code:
content[${#content[*]}]=$'\E[1;32mFinish\E[1;0m'
Code. Why this structure?

Next Edit:

The last command -
Code:
awk -F#
What the -F# does?
You have there >> script.out
But I will need to edit the script. Do I understand right, that the awk command you just mentioned, is just another form how to do it? Does it the same thing as the sed I use does? I thing so. But you just added commant to print it out at once and redirect to file. But this way: >> script.out .. it is not editing of file. It adding informations... This would corrupt the script.

Main thing I need to know now is how the condition works. Thanx for help, I leave now.

Last edited by webhope; 04-20-2010 at 09:58 AM.
 
  


Reply



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
Is there a function similar to awk for C++? binarybob0001 Programming 12 06-16-2011 04:43 PM
Absolute Value function in AWK bioinformatics_guy Linux - Newbie 3 11-02-2009 07:05 AM
awk , I need help for awk, just a display function mcandy General 1 12-15-2008 12:21 PM
How to use split function with AWK command? intikhabalam Linux - General 4 07-29-2008 10:40 AM
Need help with awk function philosophia Programming 1 02-20-2007 05:53 PM

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

All times are GMT -5. The time now is 12:24 PM.

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