LinuxQuestions.org
Visit Jeremy's Blog.
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 06-23-2020, 06:32 AM   #1
czezz
Member
 
Registered: Nov 2004
Distribution: Slackware/Solaris
Posts: 931

Rep: Reputation: 44
[BASH / SED] sed executed in script does not work


This is an example input file:
Code:
cat test.input
9fcfdec4-58a9-4612-b80a-741669bd485d\nfa17fd04-80e1-44c1-bd5e-418bdd332100\nfa17fd04-80e1-44c1-bd5e-418bdd332100
When I use following "sed" on it, it works as expected (each \n is replaced by .)
Code:
# cat test.input | sed -r 's/[\\n]+/./g'
9fcfdec4-58a9-4612-b80a-741669bd485d.fa17fd04-80e1-44c1-bd5e-418bdd332100.fa17fd04-80e1-44c1-bd5e-418bdd332100
BUT, if I try to execute it as script, it fails... what am I doing wrong???

Code:
cat script.sh
-------------
#!/bin/bash
X=`cat test.input | sed -r 's/[\n]+/./g'`
echo $X

# ./script.sh
9fcfdec4-58a9-4612-b80a-741669bd485d\nfa17fd04-80e1-44c1-bd5e-418bdd332100\nfa17fd04-80e1-44c1-bd5e-418bdd332100
 
Old 06-23-2020, 06:52 AM   #2
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,027

Rep: Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343
you do not need that cat at all:
Code:
sed 's/\\n/./g' test.input
should work.
Would be better to use $( ) instead of backticks
Code:
X=$(sed 's/\\n/./g' test.input)
echo "$X"
 
1 members found this post helpful.
Old 06-23-2020, 07:32 AM   #3
teckk
LQ Guru
 
Registered: Oct 2004
Distribution: Arch
Posts: 5,151
Blog Entries: 6

Rep: Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835
Code:
test="9fcfdec4-58a9-4612-b80a-741669bd485d\nfa17fd04-80e1-44c1-bd5e-418bdd332100\nfa17fd04-80e1-44c1-bd5e-418bdd332100"

a=`sed -r 's/[\n]+/./g' <<< "$test"`
b=$(sed -r 's/[\\n]+/./g' <<< "$test")

echo "$a"
9fcfdec4-58a9-4612-b80a-741669bd485d\nfa17fd04-80e1-44c1-bd5e-418bdd332100\nfa17fd04-80e1-44c1-bd5e-418bdd332100

echo "$b"
9fcfdec4-58a9-4612-b80a-741669bd485d.fa17fd04-80e1-44c1-bd5e-418bdd332100.fa17fd04-80e1-44c1-bd5e-418bdd332100
In your script you did not escape the \ in \n
 
1 members found this post helpful.
Old 06-23-2020, 07:33 AM   #4
crts
Senior Member
 
Registered: Jan 2010
Posts: 2,020

Rep: Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757
Quote:
Originally Posted by czezz View Post
This is an example input file:
Code:
cat test.input
9fcfdec4-58a9-4612-b80a-741669bd485d\nfa17fd04-80e1-44c1-bd5e-418bdd332100\nfa17fd04-80e1-44c1-bd5e-418bdd332100
When I use following "sed" on it, it works as expected (each \n is replaced by .)
Code:
# cat test.input | sed -r 's/[\\n]+/./g'
9fcfdec4-58a9-4612-b80a-741669bd485d.fa17fd04-80e1-44c1-bd5e-418bdd332100.fa17fd04-80e1-44c1-bd5e-418bdd332100
BUT, if I try to execute it as script, it fails... what am I doing wrong???

Code:
cat script.sh
-------------
#!/bin/bash
X=`cat test.input | sed -r 's/[\n]+/./g'`
echo $X

# ./script.sh
9fcfdec4-58a9-4612-b80a-741669bd485d\nfa17fd04-80e1-44c1-bd5e-418bdd332100\nfa17fd04-80e1-44c1-bd5e-418bdd332100
From the Bash manpage (emphasis by me):
Code:
   Command Substitution
       Command substitution allows the output of a command to replace the com‐
       mand name.  There are two forms:

              $(command)
       or
              `command`

...

       When the old-style backquote form of substitution  is  used,  backslash
       retains  its  literal  meaning except when followed by $, `, or \.  The
       first backquote not preceded by a backslash terminates the command sub‐
       stitution.   When using the $(command) form, all characters between the
       parentheses make up the command; none are treated specially.
The command substition instructions $() and `` do not behave the same. Two backslashes \\ inside `` are replaced by Bash with a single backslash \. So the sed command
Code:
echo `sed -r 's/[\\n]+/./g' test.input`
that is executed inside `` (I assume you tested the command substitution with \\ as well) is:
Code:
sed -r 's/[\n]+/./g' test.input
If you only use a single backslash \ (as you did inside your script)
Code:
echo `sed -r 's/[\n]+/./g' test.input`
then it is not treated specially by Bash inside `` because it is not followed by either $, `, or \. So the sed command that is executed executed inside `` is same as before:
Code:
sed -r 's/[\n]+/./g' test.input
The character sequence \n, however, is interpreted as a newline by sed and NOT two literal, independent characters \ and n, as is the case in your input. Since there is no actual newline in your input sed will not replace the literal character sequence \ and n.

The backslash is not treated specially by Bash when it is used inside $(), i.e., Bash passes it to sed as is. So you have two possible choices to achieve your goal:
Code:
echo `sed -r 's/[\\\n]+/./g' test.input` # three backslash
or
Code:
echo $(sed -r 's/[\\n]+/./g' test.input) # two backslash
In both cases sed will see a double backslash \\ and interpret it as one literal backslash followed by an n; as is the case in your input.

Last edited by crts; 06-23-2020 at 07:41 AM.
 
1 members found this post helpful.
Old 06-23-2020, 07:54 AM   #5
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,678

Rep: Reputation: Disabled
You can do the same with tr though:
Code:
X=$(tr -s '\\n' . <test.input)
 
1 members found this post helpful.
Old 06-24-2020, 12:59 AM   #6
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,828

Rep: Reputation: 1216Reputation: 1216Reputation: 1216Reputation: 1216Reputation: 1216Reputation: 1216Reputation: 1216Reputation: 1216Reputation: 1216
The tr is equivalent to
Code:
sed 's/[\\n]/./g' test.input
Any \ or n characters are substituted.

While
Code:
sed 's/\\n/./g' test.input
substitutes any \n string. This cannot be done with tr.
 
  


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
ShellScript executed from command prmpt but not executed from crontab or at command BMMadhav Linux - Newbie 1 11-16-2012 07:20 PM
[SOLVED] Configured Cron job executed every hour is instead executed every minute for 10m markings Linux - Software 4 05-13-2012 05:43 PM
Commands work if executed one by one in bash terminal but not from script??? taylorkh Linux - General 6 11-12-2011 07:24 AM
[SOLVED] Xwindow's program will not run when executed on boot or when executed remotely richman1234 Programming 2 10-08-2010 01:32 PM
Bash script does not behave the same when executed through /etc/rc.local bmpenev Linux - General 1 06-05-2009 11:46 AM

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

All times are GMT -5. The time now is 02:45 AM.

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