user3378876 user3378876 - 1 month ago 7
Linux Question

Parse string using shell

I want to get

NetworkActivity_5851_*_09-04-2016.done
string from
NetworkActivity_5851_2326316_09-04-2016.log.gz
and here the code I wrote

local file="$1"
local extension="${file##*.}"
if [ $extension = 'done' ]; then
local files=`basename $file`
files="${files#*_}"
files="${files#*_}"
files="${files%_*}"
local q=_"$files"_
local mask="${file/done/log.gz}"
mask="${mask/${q}/_*_}"
r=`ls "${mask}" | wc -l`


and it works correct, but when I run it with python script it fails. I mean
r
variable has wrong value.
Here is code in Python

shell = Shell(RUN_SCRIPT_2, LOGFILE)


where Shell is

class Shell():
"""
Base class for the shell script object which
is under testing.
"""

def __init__(self, path_to_script, path_to_log=None):
"""
executes shell script and store results
of STDOUT and STDERR into appropriate attributes
"""
self.path_to_log = path_to_log
# clear log file before run
if self.path_to_log:
open(self.path_to_log, 'w').close()

shell = subprocess.Popen([path_to_script],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
# the line below makes sure shell command execution finished
self.stdout, self.stderr = shell.communicate()
self.log_data = self.get_log_data()


and file path_to_script is

echo 'Start'
file="${SOURCE_DIR}/NetworkActivity_5851_3_09-04-2016.done"
extension="${file##*.}"
if [ $extension = 'done' ]; then
files=`basename $file`
files="${files#*_}"
files="${files#*_}"
files="${files%_*}"
q=_"$files"_
mask="${file/done/log.gz}"
mask="${mask/${q}/_*_}"
r=`ls "${mask}" | wc -l`
echo $r
if [ $r = $files ]; then
rez=0
else rez=1
fi
fi
if [[ $rez -eq 1 ]]; then
echo "Failure"
else echo "Success"
fi
echo 'Finish'


So when I run path_to_script from terminal
r
variable sets number of files when I run it using Python it sets 0.

Answer

You can do that using bash string-manipulation techniques alone.

$ inputString="NetworkActivity_5851_2326316_09-04-2016.log.gz"
$ substring="${inputString%%.*}"                                      # Removing the part after the first '.'
$ [[ $substring =~ .*_([[:digit:]]+)_.* ]] && NUM=${BASH_REMATCH[1]}  # Extracting the number you want to replace 
$ finalString="${substring/$NUM/*}.done"                              # Forming the final string with the extension

$ printf "%s\n" "$finalString"
NetworkActivity_5851_*_09-04-2016.done

You can put together this logic in a shell script and run the same for multiple files you have. The above commands though can be run directly on the console.

Comments