Replace string works on command-line but fails when run from shell script

I wish to replace "\\n" with a single white space.

The below does the job on command-line:

$ echo '/fin/app/scripts\\n/fin/app/01/sql' | sed -e 's#\\\\n# #g';
/fin/app/scripts /fin/app/01/sql

However, when i have the same code to a shell script it is not able to get me the same output: See below:

$ more check.sh
str=`echo "$1" | sed -e 's#\\\\n# #g'`
echo $str>check.now
$ bash -x ./check.sh '/fin/app/01/scripts\\n/fin/app/01/sql'
++ echo '/fin/app/01/scripts\\n/fin/app/01/sql'
++ sed -e 's#\\n# #g'
+ str='/fin/app/01/scripts\ /fin/app/01/sql'
+ echo '/fin/app/01/scripts\' /fin/app/01/sql
$ more check.now 
/fin/app/01/scripts\ /fin/app/01/INFENG/sql

We see the issue with "/fin/app/01/scripts\" the trailing \ at the end of the first string.

Note: I have to pass the argument to check.sh script strictly in single quotes only.

Requesting suggestions and explanations for this issue.

$ cat check.sh
str=`echo $1  | sed -e 's#[\][\]n# #g'`
echo $str>check.now
$ bash -x ./check.sh '/fin/app/01/scripts\\n/fin/app/01/sql'
++ echo '/fin/app/01/scripts\\n/fin/app/01/sql'
++ sed -e 's#[\][\]n# #g'
+ str='/fin/app/01/scripts /fin/app/01/sql'
+ echo /fin/app/01/scripts /fin/app/01/sql
$ more check.now
/fin/app/01/scripts /fin/app/01/sql
$

I think you suffer from the \ handling within `backticks`
Demonstration:

cat check.sh
str=`echo "$1" | sed -e 's#\\\\n# #g'`
echo "$str"
str=$(echo "$1" | sed -e 's#\\\\n# #g')
echo "$str"
bash ./check.sh '/fin/app/01/scripts\\n/fin/app/01/sql'
/fin/app/01/scripts\ /fin/app/01/sql
/fin/app/01/scripts /fin/app/01/sql

You could try something like this:
Longhand OSX 10.14.3, default bash terminal using 'dash'...

Last login: Tue Sep  3 18:18:39 on ttys000
AMIGA:amiga~> dash
AMIGA:\u\w> text='oiweroiweroi oieurowir lkj
> asdkjd pqowepom,xcm909184 ;lk
> 0912830980n kjhksjdfkj oizxc
> 
> '
AMIGA:\u\w> echo "${text}"       
oiweroiweroi oieurowir lkj
asdkjd pqowepom,xcm909184 ;lk
0912830980n kjhksjdfkj oizxc


AMIGA:\u\w> text1=$( echo $text )
AMIGA:\u\w> echo "${text1}"
oiweroiweroi oieurowir lkj asdkjd pqowepom,xcm909184 ;lk 0912830980n kjhksjdfkj oizxc
AMIGA:\u\w> exit
AMIGA:amiga~> _

Why sed ? Try "parameter expansion":

echo ${1//\\\\n/ }
/fin/app/01/scripts /fin/app/01/sql

Fully POSIX compliant using OP's parameters:

#!/usr/local/bin/dash
# check.sh
# $1 is '/fin/app/01/scripts\\n/fin/app/01/sql'

text=$( echo $( echo $1 ) )
echo $text

Results using as before...

Last login: Tue Sep  3 23:00:12 on ttys000
AMIGA:amiga~> cd Desktop/Code/Shell
AMIGA:amiga~/Desktop/Code/Shell> ./check.sh '/fin/app/01/scripts\\n/fin/app/01/sql'
/fin/app/01/scripts /fin/app/01/sql
AMIGA:amiga~/Desktop/Code/Shell> _

Sorry, but it does not give correct output. See below:

Look at the trailing \ after the first string /fin/app/01/scripts\

cat check.sh
str=`echo ${1//\\\\n/ }`
echo $str>check.row

--- Post updated at 05:11 AM ---

This does not work for me. See my test below.

cat check.sh
str=$( echo $( echo $1 ) )
echo $str>check.row

Also, I intend to run this on ksh shell as well.

--- Post updated at 05:13 AM ---

This is not a new line but delimiter of type string "\\n" i guess.

--- Post updated at 05:26 AM ---

@MadeInGermany you seem to have highlighted the core point of this issue.

However, I wanted to know if there is a solution for ksh shell on AiX with backticks ? A non-sed solution would also do. Thank you!!

The echo command is not portable.
Use printf "%s\n" instead.

cat check.sh
str=`printf "%s\n" "$1" | sed -e 's#\\\\n# #g'`
printf "%s\n" "$str"
str=$(printf "%s\n" "$1" | sed -e 's#\\\\n# #g')
printf "%s\n" "$str"

Now ksh and bash should have the same behavior.

1 Like

This uses '/usr/bin/printf' which is fully POSIX compliant.
Just use your 'printf':

#!/usr/local/bin/dash
# check.sh
# Use /usr/bin/printf as that is fully POSIX compliant.
# OSX 10.14.3...
# $1 is '/fin/app/01/scripts\\n/fin/app/01/sql'

text=$( /usr/bin/printf "%b" $( /usr/bin/printf "%b" $1 ) )
text=$( /usr/bin/printf "%b " ${text} )

# Without trailing newline:
# /usr/bin/printf "%s" "${text%?}" > /tmp/check.row

# With trailing newline:
/usr/bin/printf "%s\n" "${text%?}" > /tmp/check.row

# Check results...
echo ""
cat /tmp/check.row
echo ""
hexdump -C /tmp/check.row
echo ""

Results using the same machine as before.

Last login: Wed Sep  4 10:27:46 on ttys000
AMIGA:amiga~> cd Desktop/code/Shell
AMIGA:amiga~/Desktop/code/Shell> ./check.sh '/fin/app/01/scripts\\n/fin/app/01/sql'

/fin/app/01/scripts /fin/app/01/sql

00000000  2f 66 69 6e 2f 61 70 70  2f 30 31 2f 73 63 72 69  |/fin/app/01/scri|
00000010  70 74 73 20 2f 66 69 6e  2f 61 70 70 2f 30 31 2f  |pts /fin/app/01/|
00000020  73 71 6c 0a                                       |sql.|
00000024

AMIGA:amiga~/Desktop/code/Shell> _
1 Like