0

So I manually use the following two commands in succession on my data file, i.e. I trigger the second command after the first has finished updating the file:

sed -i 's/""""/" " /g' EXPERIMENT-20210729010003.FILE
sed -i 's/"""/" " /g' EXPERIMENT-20210729010003.FILE

How can i write this in a .sh script and pass file name as argument to the sh call?

EXPERIMENT-*.FILE comes everyday on my unix server. At any given point of time there can be only one Experiment file with a unique datetime value appended to its name.

Thanks!

αғsнιη
  • 41,407

2 Answers2

0

Basically what you're looking for is:

#!/bin/bash
sed -i 's/""""/" " /g' $1
sed -i 's/"""/" " /g' $1
exit 0

Lets say you name the script myscript.sh. You'd use it like so:

./myscript.sh filename.txt

The $1 is the first argument that is passed to the script, in this case filename.txt.

All a bash/shell script is, is just a bunch of commands that you can run manually, but instead automate those commands all in one.

AdminBee
  • 22,803
CPH
  • 105
  • 2
0

You could combine your two separate sed commands into one:

sed -i -e 's/""""/" " /g' -e 's/"""/" " /g' file

or even,

sed -i 's/"\{3,4\}/" " /g' file

(but only because """" is being replaced before """; had you done the substitutions in the opposite order, then this last command would not be equivalent).

You could turn this into a shell script,

#!/bin/sh

sed -i -e 's/""""/" " /g' -e 's/"""/" " /g' -- "$@"

... or into a shell function (in your ~.bashrc file, for example),

call_sed () {
    sed -i -e 's/""""/" " /g' -e 's/"""/" " /g' -- "$@"
}

The -- in the command stops command line option processing and allows you to use the script or function on filenames starting with a dash. The "$@" will expand to a list of filenames given to the script or function, each individually quoted.

You could use the script or function like so:

$ call_sed EXPERIMENT-*.FILE

With a single sed command like this, you could even make it an alias, but the quoting needs to be handled with care and I would recommend using a shell function instead:

alias call_sed='sed -i -e "s/\"\"\"\"/\" \" /g" -e "s/\"\"\"/\" \" /g" --'

To make the -i option (which you may not want to use always) an option to the script:

#!/bin/sh

unset in_place

if [ "$1" = "-i" ]; then in_place=true shift fi

sed ${in_place:+-i} -e 's/""""/" " /g' -e 's/"""/" " /g' -- "$@"

The ${in_place:+-i} would expand to -i if $in_place is non-empty. The variable would be non-empty if the first argument given to the script is -i.

The exact same modification could be made to the shell function variant of the code to make the shell function take an -i option.

Kusalananda
  • 333,661
  • A call to sed like sed 's/"\{3,4\}/" " /g' is a good enough regex to match both sequences of 4 double quotes """" and/or 3 double quotes """. –  Jul 30 '21 at 06:41
  • @ImHere Since it will match the longest match first, it will produce the same result. If """" had been replaced before """"", the results would have been different. I'll make a note in my answer. Thanks! – Kusalananda Jul 30 '21 at 06:50
  • If you replace 3 """ first, there will be no 4 """" to replace anymore. –  Jul 30 '21 at 07:37
  • @ImHere Exactly, this is why your suggestion works in this case, but not if the user in the question had done the substitutions in the opposite order. – Kusalananda Jul 30 '21 at 08:28
  • Thank you @Kusalananda. That was very detailed and useful. :) – BasicQs Jul 31 '21 at 20:12