#linux #bash #shell
#linux #bash #оболочка
Вопрос:
Я хочу получить NetworkActivity_5851_*_09-04-2016.done
строку из NetworkActivity_5851_2326316_09-04-2016.log.gz
и вот код, который я написал
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`
и это работает правильно, но когда я запускаю его с помощью скрипта python, происходит сбой. Я имею в виду, что r
переменная имеет неправильное значение.
Вот код на Python
shell = Shell(RUN_SCRIPT_2, LOGFILE)
где оболочка
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()
и путь к файлу_to_script равен
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'
Итак, когда я запускаю path_to_script из терминала, r
переменная задает количество файлов, когда я запускаю ее с помощью Python, она устанавливает 0.
Комментарии:
1. @Inian это должен быть номер файла, который имеет имя в качестве шаблона
Ответ №1:
Вы можете сделать это, используя bash
только методы манипулирования строками.
$ inputString="NetworkActivity_5851_2326316_09-04-2016.log.gz"
$ substring="${inputString%%.*}" # Removing the part after the first '.'
$ [[ $substring =~ .*_([[:digit:]] )_.* ]] amp;amp; NUM=${BASH_REMATCH[1]} # Extracting the number you want to replace
$ finalString="${substring/$NUM/*}.done" # Forming the final string with the extension
$ printf "%sn" "$finalString"
NetworkActivity_5851_*_09-04-2016.done
Вы можете объединить эту логику в сценарий оболочки и запустить то же самое для нескольких имеющихся у вас файлов. Вышеуказанные команды, однако, могут быть запущены непосредственно на консоли.
Комментарии:
1. Есть еще одна проблема, если
_2326316_
будет_8_
, например.${substring/$NUM/*}.done
заменяет первое вхождение 8. Я пытался${substring/_$NUM_/_*_}.done
, но это заменяет первое вхождение _
Ответ №2:
Ну, я основываюсь на вашем первом абзаце. Надеюсь, я понял проблему! Это мое решение с использованием Perl и регулярных выражений с помощью простой командной строки.
~$ gunzip NetworkActivity_5851_2326316_09-04-2016.log.gz amp;amp; perl -e 'while(<>){print $_ if $_ =~ /NetworkActivity_d _.*_d{2}-d{2}-d{4}.done/}' NetworkActivity_5851_2326316_09-04-2016.log
Надеюсь, это поможет!