Insert LineFeed into string? ( echo -e ) [ Solved ]

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Post Reply
Message
Author
User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

Insert LineFeed into string? ( echo -e ) [ Solved ]

#1 Post by sunburnt »

Like this:

Code: Select all

A='1'\x0a'2'
Or:

Code: Select all

echo '1'\x0a'2'
But the hex code for LineFeed ( \x0a ) doesn`t seem to work.
I use to use a real LineFeed in the string, but it doesn`t work anymore.
Last edited by sunburnt on Mon 19 Sep 2011, 02:41, edited 2 times in total.

User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

#2 Post by sunburnt »

This works, but you`d think the hex would work also.

Code: Select all

A=`echo -e '1\n2'`

jpeps
Posts: 3179
Joined: Sat 31 May 2008, 19:00

#3 Post by jpeps »

printf "hello\x0aMy Friend"

or

echo -e "hello\x0aMy Friend"

echo -e '1\x0a2'

User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

#4 Post by sunburnt »

Of course... The extended echo recognizes it... Duh!

# Thanks jpeps... How`s it going?
What have you been doing lately?

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#5 Post by technosaurus »

echo -e is not portable, but this is:

Code: Select all

A="1
2
3
"

echo "$A"
#or
echo "${A}"
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

jpeps
Posts: 3179
Joined: Sat 31 May 2008, 19:00

#6 Post by jpeps »

sunburnt wrote:Of course... The extended echo recognizes it... Duh!

# Thanks jpeps... How`s it going?
What have you been doing lately?
running stock scans

User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

#7 Post by sunburnt »

technosaurus; The problem was converting a comma delimited string into a list.
So a sed type thing to substitute 'LF' for ', '

I use to use this, but it doesn`t work anymore:

Code: Select all

echo '1, 2, 3' |sed 's/, /
/'
jpeps; More disaster I fear... But there`s still money to be made.

jpeps
Posts: 3179
Joined: Sat 31 May 2008, 19:00

#8 Post by jpeps »

sunburnt wrote:I use to use this, but it doesn`t work anymore:

Code: Select all

echo '1, 2, 3' |sed 's/, /
/'
.
echo "1,2,3,4" | sed 's/,/\x0a/g'

User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

#9 Post by sunburnt »

jpeps; Yes, it`s interesting that sed and echo -e recognizes the hex
representation of a character, but the Bash command line doesn`t.

It seems like this would have been corrected a long time ago.

jpeps
Posts: 3179
Joined: Sat 31 May 2008, 19:00

#10 Post by jpeps »

sunburnt wrote:jpeps; Yes, it`s interesting that sed and echo -e recognizes the hex
representation of a character, but the Bash command line doesn`t.

It seems like this would have been corrected a long time ago.
It does recognize it. Echo -e interprets it as a hex.

A="1\x0a2" ; echo -e "$A"

You might want to just print the literal.

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#11 Post by technosaurus »

why didn't you say so - here is the portable way to do that

Code: Select all

A="1,2,3,4"
echo "${A//,/
}"
or to get the data from some command

Code: Select all

A=`somecommand`
echo "${A//,/
}"
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

jpeps
Posts: 3179
Joined: Sat 31 May 2008, 19:00

#12 Post by jpeps »

technosaurus wrote:why didn't you say so - here is the portable way to do that
only problem is 7 extra lines, one for the linefeed and five to explain that it contains invisible code:

sample @copyright 2011

## WARNING. IF THE SCRIPT NO LONGER WORKS, IT'S PROBABLY BECAUSE YOU TRIED TO TIDY IT UP A BIT BY REMOVING THAT EXTRA LINE, DIDN'T YOU? WELL THAT EXTRA LINE INCLUDED A LINEFEED...IT'S INVISIBLE, BUT THAT DOESN'T MEAN YOU DON'T NEED IT, DOES IT? IF YOU FORGOT WHAT THE ORIGINAL CODE LOOKED LIKE, YOU'LL NEED TO GET HELP, OR FIND ANOTHER COPY.

User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

#13 Post by sunburnt »

jpeps; Yes, visible code is usually preferable to the invisible variety.

technosaurus does show the pure Bash code.
I tend to think of cp, ls, sed, grep, awk, etc. as separate from Bash.
But it does demonstrate that Bash doesn`t do hex characters, right?

User avatar
MinHundHettePerro
Posts: 852
Joined: Thu 05 Feb 2009, 22:22
Location: SE

#14 Post by MinHundHettePerro »

sunburnt wrote:I tend to think of cp, ls, sed, grep, awk, etc. as separate from Bash.
Is "echo -e" also to be regarded as separate from Bash?
Pardon my question, I'm just a non-purist :shock: :).

If it is, then just scratch this (and accept my non-purist apologies):

Code: Select all

# A="1,2,3,4"      
# echo -e "${A//,/\x0a}"
Cheers :oops:/ MHHP
[color=green]Celeron 2.8 GHz, 1 GB, i82845, many ptns, modes 12, 13
Dual Xeon 3.2 GHz, 1 GB, nvidia quadro nvs 285[/color]
Slackos & 214X, ... and Q6xx
[color=darkred]Nämen, vaf....[/color] [color=green]ln -s /dev/null MHHP[/color]

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#15 Post by technosaurus »

Echo -e will not work in dash iirc ... its a bashism
If you use it, with bin/sh shabang in Debian it will fail

If its only a little more code I try to use shell builtins vs sed/grep/awk/cut/tr
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

potong
Posts: 88
Joined: Fri 06 Mar 2009, 04:01

#16 Post by potong »

technosaurus: printf can replace echo (and I think it's posix too):

Code: Select all

# string='a,b,c,d,e'
# echo -e "${string//,/\n}"
a
b
c
d
e
# printf "${string//,/\n}\n"
a
b
c
d
e
Of course you have to remember to add your own newline!
For those that like to work with arrays (non-posix?)

Code: Select all

# IFS=, read -ra array <<<"$string"
# for i in "${!array[@]}";do printf "\${array[$i]}=\"${array[$i]}\"\n";done
${array[0]}="a"
${array[1]}="b"
${array[2]}="c"
${array[3]}="d"
${array[4]}="e"
# new_string=$(IFS=$'\n';printf "${array[*]}")
# printf "$new_string\n"
a
b
c
d
e
Basically this uses the $IFS variable to split the string into an array. Then uses it again to combine back into a string

Code: Select all

# another_string=$(printf "%s" "${array[@]/%/\n}")
# printf "$another_string"
a
b
c
d
e
Another way to achieve the same ends is to append a newline to each element of an array and then print the each element of the array.
But beware there is a gotcha:

Code: Select all

# yet_another_string=$(IFS=;printf "${array[*]/%/\n}")
# printf "$yet_another_string"
a
b
c
d
e# printf "$yet_another_string"|od -acx
0000000   a  nl   b  nl   c  nl   d  nl   e nul
          a  \n   b  \n   c  \n   d  \n   e  \0
        0a61 0a62 0a63 0a64 0065
0000011
The first printf "$string" chomps the last newline!! So use:

Code: Select all

# yet_another_string=$(IFS=;printf "%s" "${array[*]/%/\n}")
# printf "$yet_another_string"|od -acx
0000000   a  nl   b  nl   c  nl   d  nl   e  nl
          a  \n   b  \n   c  \n   d  \n   e  \n
        0a61 0a62 0a63 0a64 0a65
0000012
HTH

Potong

big_bass
Posts: 1740
Joined: Mon 13 Aug 2007, 12:21

#17 Post by big_bass »

this adds a new line to every character in a string

Code: Select all

string="Vertical"
echo -n "string" | sed 's/./&@/g '| tr '@' '\n' 
you can pass the octal code number too but more difficult to remember but very powerful combined with this http://www.asciitable.com/

Code: Select all

string="Vertical"
echo -n "string" | sed 's/./&@/g '| tr '@' '\012' 

this removes the last space from the string

Code: Select all

string="Vertical"
echo -n "string" | sed 's/./&@/g; s/@$//' | tr '@' '\012'



Note that the "sed" command adds a '@' character after every character,
except at the end of the string.
The "tr" then replaces the '@' characters with newlines.
It also assumes the input text does not end with a newline,
which would cause an extra blank space to be added at the
bottom

*I got and use that snippet from imagemajick



if you play with octal codes you can do many cool things the
forum doesnt show the format of these but they work
string="Verticaltabs"
echo -n "string" | sed 's/./&@/g '| tr '@' '\013'


string="bigtabs"
echo -n "string" | sed 's/./&@/g '| tr '@' '\011'



Joe

potong
Posts: 88
Joined: Fri 06 Mar 2009, 04:01

#18 Post by potong »

Nearly forgot!

Code: Select all

# yas=$(set a b c d e;printf "%s\n" "$@")
# printf "$yas\n"
a
b
c
d
e
For an array-like method good for functions.
Lastly... "%s\n" can be any kind of format you like, check it out here.

HTH

Potong

p.s. big_bass: if your using gnu sed

Code: Select all

# sed 's/,/\n/g' <<<"a,b,c,d,e"
a
b
c
d
e
works too!

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#19 Post by technosaurus »

yes with some shells it ($@) is the only way to get array-like behavior (busybox ash and hush included)

ex

#print $3 - $8
echo ${@:3:6}

#print last 5 vars
POS=$(($#-5))
echo ${@:$POS:5}

or here is a practice script that I wrote to implement tail
it changes the separator so that set will store each line as a separate variable (line 1 is $1 and last line is $#)

Code: Select all

#!/bin/ash

tail_help(){
echo "tail -[cnqv] files"
exit
}

[ $1 ] || tail_help

while ([ $# > 0 ]) do
	case $1 in
	-h|--help)tail_help;;
	--version)echo "tail v0.0";exit;;
	-c)BYTES=${2};shift;shift;;
	--bytes=*)BYTES=${1%=*};shift;;
	-n)LINES=${2};shift;shift;;
	--lines=*)LINES=${1%=*};shift;;
	-q|--quiet|--silent)QUIET=1;shift;;
	-v|--verbose)VERBOSE=1;shift;;
	#todo -f and -s
	*)[ -f ${1} ] && break || tail_help;;
	esac
done

#for -f while goes here
for FILE in $@; do
	HEADER="==> "$FILE" <=="
	[ ! $QUIET ] && [ $# -gt 1 ] || [ $VERBOSE ] && echo $HEADER
#	while read LINE || [ $LINE ] && echo $LINE && LINE=""; do echo $LINE; done <"${FILE}"
	A=`while read -r LINE; do echo $LINE; done <"${FILE}";echo $LINE`
	[ ${#A} -lt 1 ] && echo && continue
	if [ $BYTES ];then
		#for -f compare BYTES to new $#A - old $#A and print the lesser
		i=$((${#A}-$BYTES))
		echo "${A:$i:$BYTES}"
	else
		OLDIFS=$IFS
		IFS="
"
		set ${A}
		#for -f get size here and compare to last
		LINES=${LINES:-10}
		shift $(($#-$LINES))
		for LINE in $@; do
			echo "${LINE}"
		done
		IFS=$OLDIFS
	fi

done
you can do a lot with IFS, set and string manipulation without having to use anything external to the shell
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

big_bass
Posts: 1740
Joined: Mon 13 Aug 2007, 12:21

#20 Post by big_bass »

Potong

p.s. big_bass: if your using gnu sed
Code:
# sed 's/,/\n/g' <<<"a,b,c,d,e"
a
b
c
d
e
works too!
hey potong nice thanks and without commas needed to separate
like this even more compact code

Code: Select all

sed 's/./&\n/g' <<<"string" 

for every single character show the single character and a new line


Joe

Post Reply