Read line, issue with leading - and {}'s

Heyas

With my forum search term 'issue with leading dash' i found 2 closed threads which sadly didnt help me.

Also me was to eager to add the script, that i didnt properly test, and just now figured this issue.

So i have this code:

if [[ -f "$arg" ]]
then 	while read line
	do	line="${line/-/'\-'}"
		#line="$(echo $line|sed s,{},&\,g)"
		line=$(echo "$line"|$SED 's|[%$/\|\]|\\&|g')
		tui-echo "$line"
	done<"$arg"
else	tui-status 1 "File not found: $arg"
fi

I had also tried line=$(echo "$line"|$SED 's|{%$/\|\}|\\&|g') but that didnt work on the {} and %

And attempting to print text like:

mv %{name}/docs/*       %{buildroot}%{_docdir}/%{name}
mv %{name}/man/*.1      %{buildroot}%{_mandir}/man1

# Lets try once again without this...
rm -fr  %{name}/profile.d/tui.sh
#mv %{name}/profile.d/tui.sh	%{buildroot}%{_sysconfdir}/profile.d/tui.sh
# Keep for compatiblity
touch %{buildroot}%{_sysconfdir}/profile.d/tui.sh

%clean
rm -rf %{buildroot}

%files
%defattr(-,root,root,-)   
%doc %{_docdir}/%{name}/
%{_mandir}/man1/%{name}*.1.gz
%{_datarootdir}/%{name}/
%{_bindir}/%{name}
%{_bindir}/%{name}-*
#%{_sysconfdir}/%{name}/
#%{_sysconfdir}/profile.d/%{name}.sh

%config
%{_sysconfdir}/%{name}/
%{_sysconfdir}/profile.d/%{name}.sh
%{_sysconfdir}/bash_completion.d/%{name}_compl.bash

%changelog
* Wed Jan 21 2015 - Simon A. Erat - erat.simon@gmail.com - 0.6.8-4
- Added:   tui-cat, prints a file, also offers typewriter mode
- Updated: tui-new-script, renamed medium to default, added 'tool'

Now the current issue cause the most trouble is the leading - of the %changelog section.

But what i get is:

# | mv /bin/tui-printf: Zeile 354: printf: `{': Ung�ltiges Formatierungszeichen.
# |                                                                                                              | #
# | # Lets try once again without this...                                                                        | #
/bin/tui-printf: Zeile 354: printf: `{': Ung�ltiges Formatierungszeichen.
# | rm \-fr  /bin/tui-printf: Zeile 354: printf: `{': Ung�ltiges Formatierungszeichen.
# | # Keep for compatiblity                                                                                      | #
/bin/tui-printf: Zeile 354: printf: `{': Ung�ltiges Formatierungszeichen.
# |                                                                                                              | #
# | lean                                                                                                       | #
/bin/tui-printf: Zeile 354: printf: `{': Ung�ltiges Formatierungszeichen.
# |                                                                                                              | #
# | 0.000000iles                                                                                                       | #
# | 0efattr(\-,root,root,-)                                                                                     | #
/bin/tui-printf: Zeile 354: printf: `{': Ung�ltiges Formatierungszeichen.
# | 0oc /bin/tui-printf: Zeile 354: printf: `{': Ung�ltiges Formatierungszeichen.
# | /bin/tui-printf: Zeile 354: printf: `{': Ung�ltiges Formatierungszeichen.
# | /bin/tui-printf: Zeile 354: printf: `{': Ung�ltiges Formatierungszeichen.
# | /bin/tui-printf: Zeile 354: printf: `{': Ung�ltiges Formatierungszeichen.
# | /bin/tui-printf: Zeile 354: printf: `{': Ung�ltiges Formatierungszeichen.
# | #/bin/tui-printf: Zeile 354: printf: `{': Ung�ltiges Formatierungszeichen.
# |                                                                                                              | #
# | onfig                                                                                                      | #
/bin/tui-printf: Zeile 354: printf: `{': Ung�ltiges Formatierungszeichen.
# | /bin/tui-printf: Zeile 354: printf: `{': Ung�ltiges Formatierungszeichen.
# | /bin/tui-printf: Zeile 354: printf: `{': Ung�ltiges Formatierungszeichen.
# |                                                                                                              | #
# | hangelog                                                                                                   | #
# | * Wed Jan 21 2015 \- Simon A. Erat - erat.simon@gmail.com - 0.6.8-4                                          | #
# | \- Added:   tui-cat, prints a file, also offers typewriter mode                                              | #
# | \- Updated: tui-new-script, renamed medium to default, added 'tool'                                          | #
# |       

Guess i'll try now a sed instead of a substition on the first line modification, as i just want a leading dash escaped, not every dash.
If that should work, the question on % and {} remains though.

Thank you

---------- Post updated at 12:21 ---------- Previous update was at 12:09 ----------

Changed to:

[[ "-" = "${line:0:1}" ]] && \
	line="${line/-/'\-'}"
line=$(echo "$line"|$SED s,'{%}','\\&',g)

But still no luck.

Oh wait... /bin/tui-printf: Zeile 354: printf

cat -n $(which tui-printf) | grep 354 -B3

   351	#
   352	#	Display & Action
   353	#
   354		printf "${COLOR_LINE_START}${BORDER_LEFT}${COLOR_LINE_IDENT} ${FIRST}${SECOND}${THIRD} ${COLOR_LINE_CLOSE}${BORDER_RIGHT}${COLOR_LINE_END}"

Should i attempt this in tui-printf or in tui-cat?

What troubles me the most is this (inside tui-cat):

  • If i dont escape the leading dash, it fails on tui-printf/printf/echo.
  • If i escape the leading dash, it prints the escape char too.

Confused.

---------- Post updated at 13:52 ---------- Previous update was at 12:21 ----------

# % works now:
#line=$(echo "$line"|$SED s,'%','%%',g)
#line=$(echo "$line"|$SED s,'%','\%%',g)
#line=$(echo "$line"|$SED s,'\%','\%\%',g)
#line=$(echo "$line"|$SED s,'\%','\\%',g)
line=$(echo "$line"|$SED s,"%","%%",g)

# Fails to preserve, virtual line continueation: \<newline> (eg: [[ condition ]] && \)
#line=$(echo "$line"|$SED s,"\\","\\\\",g)
line=$(echo "$line"|$SED s,'\\','\\\\',g)

# Not there to fix yet
line=$(echo "$line"|$SED s,'{','\{',g)
line=$(echo "$line"|$SED s,'}','\}',g)
tui-echo "$line"

Me out of ideas now, thank you in advance for any ideas.

I don't quite understand what you want. What is the difference between a leading dash, and every other dash? If you can define that precisely, you'll have mostly solved the problem.

It looks like you have some kind of home-grown library: tui-printf tui-echo
It appears not to deal with whatever you have been sending it.

I may be delusional but I think this will work:

if [[ -f "$arg" ]]
then 	
        awk '{ dash=substr($0,1,1); 
                  if(dash=="-") {$0=substr($0,2)}; print}'  "$arg" |
        while read line
	do	
             tui-echo "$line"
	done 
else	tui-status 1 "File not found: $arg"
fi

The reason this will probably work is that you no longer have the shell intervening to mess with and get confused by } and other characters.

Note: line is also a command and it functions as read line does.
Using a command name as variable name is usually a bad idea.

You could try:

        awk '{ dash=substr($0,1,1); 
                  if(dash=="-") {$0=substr($0,2)}; print}'  "$arg" | xargs tui-echo

if tui-echo deal with the output.

1 Like

printf has special treatment for % in its first argument.
The fix is easy: Have %s in the first argument. Change

 354        printf "${COLOR_LINE_START}${BORDER_LEFT}${COLOR_LINE_IDENT} ${FIRST}${SECOND}${THIRD} ${COLOR_LINE_CLOSE}${BORDER_RIGHT}${COLOR_LINE_END}"

to

 354        printf "%s" "${COLOR_LINE_START}${BORDER_LEFT}${COLOR_LINE_IDENT} ${FIRST}${SECOND}${THIRD} ${COLOR_LINE_CLOSE}${BORDER_RIGHT}${COLOR_LINE_END}"
1 Like

@ Corona:
The leading 'dash' produces an error like (Just the same way as printf does :: was the first/last i could find when scrolling up from yesterdays terminal output):

# |                                                                                                              | #
# | * Thu Dec 18 2014 - Simon A. Erat - erat.simon@gmail.com - 0.6.4-0                                           | #
/bin/tui-printf: Invalid Option --  

tui-printf (1.4)
tui-printf
Usage: 	tui-printf [options] [arguments]
	tui-printf		Prints up to 3 arguments. 
			1: Left
			2: Left, Right
			3: Left, Center, Right
Arguments will tell tui-printf if and where to colorize, or if to do a linebreak.

Obviously this error appears as many times there is a leading dash, which is required by the specfile to list items.
Though, its more thought to print 'simple' text files, rather than 'scripts' like this.

--> @ Jim: Yes.
Hope xargs preserves argument strings?
Anyway, i will see what happens.

@ MadeInGermany
The % was in some way the least of the issues , but i try it 'that' way and see if it fixes the alignment.

Thinking...
Since its tui-printf issueing the leading dash, as that indicates an option/argument for tui-printf uses getopts to parse them, it could be a good idea to catch this (the leading dash) in tui-printf.
So another, fetching wrong option to catch in a tempvar and reuse that tempvar in the final output (354) again, hopeing there will be no splitting up, though i could just pass the tempvar again, and let itself handle it again when the string matches on the line...

But first, i'll do what you suggested.

---------- Post updated at 11:43 ---------- Previous update was at 11:03 ----------

With the changes from MadeInGermany (only), i get (regardles of '%s' or "%s" or even echo -n "-teststring" ):

tui-cat /home/sea/prjs/tui/tui.spec 
\r\033[0m# | Name:        tui                                                                                             | #\033[0m\n\033[0m\r\033[0m# | Version:     0.6.8                                                                                           | #\033[0m\n\033[0m\r\033[0m# | Release:     9%%{?dist}                                                                                      | #\033[0m\n\033[0m\r\033[0m# | Summary:     A line based Text User Interface framework for scripts                                          | #

@ Jim
Now i dont get any of the dashes to see.
They are part of the output, so i want to preserve them for the output, they just keep interfeering with:

printf "-teststring"
bash: printf: -t: Invalid Option
printf: Use: printf [-v var] Format [Argumente]

Figured, ty M.I.G., that tui-echo didnt print "This is 100%" well, so i've added the escaping from tui-cat to tui-printf, which does the tui-echo output, which is again used by tui-cat. Easy huh :stuck_out_tongue:

Anyway, since that works quite good, i can finaly be precice on my question:

I need to know a way so i can pass a string to a command, so it prints a leading dash without failing, give it also has the 'power' of printf.
Or something that helps to preserve the leading dash for the output, without crashing the expected output, and to print the escape char for the leading dash, as shown in first post.

Any further ideas please?
Thank you in advance.

---------- Post updated at 12:33 ---------- Previous update was at 11:43 ----------

For the leading dash, i put in a single empty spacechar and renamed line to content.
Tui-cat now uses this:

			if [[ -f "$arg" ]]
			then 	while read content
				do	[[ "-" = "${content:0:1}" ]] && \
						content=" ${content}"
					tui-echo "${content}"
				done<"$arg"
			else	tui-status 1 "File not found: $arg"
			fi

As of now, the % fix is:

	# Escape '%'
	output=$(echo "${COLOR_LINE_START}${BORDER_LEFT}${COLOR_LINE_IDENT} ${FIRST}${SECOND}${THIRD} ${COLOR_LINE_CLOSE}${BORDER_RIGHT}${COLOR_LINE_END}"|$SED s,'%','%%',g)
	printf "$output"

So me now have only one remaining issue:

# | mkdir -p     %{buildroot}%{_bindir}/                      %{buildroot}%{_mandir}/man1                        | #
# |                               %{buildroot}%{_sysconfdir}/%{name}/                      %{buildroot}%{_syscon | #
# |                 fdir}/profile.d/                      %{buildroot}%{_datarootdir}/%{name}/themes             | #
# |                          %{buildroot}%{_docdir}/%{name} 		     %{buildroot}%{_sysconfdir}/bash_completion.d/ | #

Should actualy look like (keep format/idention, show the backslash):

mkdir -p     %{buildroot}%{_bindir}/ \
                     %{buildroot}%{_mandir}/man1 \
                     %{buildroot}%{_sysconfdir}/%{name}/ \
                     %{buildroot}%{_sysconfdir}/profile.d/ \
                     %{buildroot}%{_datarootdir}/%{name}/themes \
                     %{buildroot}%{_docdir}/%{name} \
		     %{buildroot}%{_sysconfdir}/bash_completion.d/

My best guess is (in tui-printf):

# Change/switch leading space-dash
	[[ " -" = "${FIRST:0:2}" ]] && \
		FIRST="${FIRST:1} " # Trailing space is a _MUST_ to keep alignment intact, as it got counted when the space was leading
	# Escape trailing backslash, from whichever argument passed
	echo "$FIRST" | grep -q "\\"$ && \
		FIRST="${FIRST}\\\\"
	echo "$SECOND" | grep -q "\\"$ && \
		SECOND="${SECOND}\\\\"
	echo "$THIRD" | grep -q "\\"$ && \
		THIRD="${THIRD}\\\\"
	
	# Escape '%'
	output=$(echo "${COLOR_LINE_START}${BORDER_LEFT}${COLOR_LINE_IDENT} ${FIRST}${SECOND}${THIRD} ${COLOR_LINE_CLOSE}${BORDER_RIGHT}${COLOR_LINE_END}"|$SED s,'%','%%',g)
	
	# The actual output
	printf "$output"

My other attempt also doesnt seem to work (in tui-cat):

# Tailing backslash
	[[ ! -z "$content" ]] && \
		[[ "\\" = "${content:0:(-1)}" ]] && \
		content="${content}\\\\"

But still dont even see the tailing \...
Any ideas

Hi,

$ printf "-teststring\n"
-bash: printf: -t : option non valable
printf: usage: printf [-v var] format [arguments]
$ printf -- "-teststring\n"
-teststring

Regards.

1 Like

Better

printf "%s" "-teststring\n"

or

printf "%s\n" "-teststring"

that covers also a "-test%string" .

I'm afraid that any variation of

printf '%s' "string"

messes up all the 'display'.
And i dont want to use eval to get the colors prints properly, as i dont want to execute other possible variables placed as output. (See 5th post - 1st -enlared post to it)

Sorry I forgot to add solved.