我目前正在开发一个bash脚本,脚本的内容将提示用户输入目录路径,并将目录路径存储在变量中。然后,我将目录路径中的文件复制到我的路径,将文件(.html)转换为(.xls)。之后,我使用mailx命令通过电子邮件发送(.xls)文件。但是,文件可能超过1,并且每周都不会修复。
#!/bin/bash
echo "Enter the path: (e.g. /a/b/c/d/e/f/g/h/i/system_name/24_july/full_file)"
read directory
systemname=$(echo $directory | cut -d'/' -f11) #-f11 indicates 'system_name"
dates=$(echo $directory | cut -d'/' -f12) #-f12 indicates '24_july'
cp $directory/mode1/consolidate_full_file/file.mode1/output_mode1/file.html .
mv file.html MODE1_NAME.xls
cp $directory/mode2/consolidate_full_file/file.mode2/output_mode2/file.html .
mv file.html MODE2_NAME.xls
echo "Sending files of $systemname on $dates" | mailx -s "Test" -a MODE1_NAME.xls -a MODE2_NAME.xls mmaz@hotmail.com
因此,我打算要求用户创建一个文本文件,其中包含system_name,目录路径,本周存在的模式。从该文本文件,我打算从bash脚本打开它并获取所需的所有数据。有可能吗?
这是文本文件blocka.txt的示例:
systemname=blocka
directory=/a/b/c/d/e/f/g/h/i/system_name/24_july/full_file
List of modes:
MODE1_NAME= /a/b/c/d/e/f/g/h/i/system_name/24_july/full_file/mode1/consolidate_full_file/file.mode1/output_mode1/file.html
MODE2_NAME= /a/b/c/d/e/f/g/h/i/system_name/24_july/full_file/mode2/consolidate_full_file/file.mode2/output_mode2/file.html
End of List of modes
我试图找到系统名称和目录的字符串匹配,但是如何识别模式列表之间存在模式:直到模式列表结束。
从blocka.txt,我需要获取所需的数据作为变量,以便我可以减少bash脚本中的硬编码。我有什么方法可以尝试这种方式吗?因为我认为它足够有效,因为任何系统名称都可以通过对文本文件进行makig更改来使用它。
答案 0 :(得分:0)
最简单的方法是使用source
,它基本上运行目标文件,保持变量设置。但是,这是不安全的,允许人们将他们想要的任何代码插入到文件中并让主脚本运行它。
相反,我们可以运行while
循环,逐行读取文件,并检查一组if
语句。
#!/bin/bash
while IFS= read -r line; do
#If the current line starts with "systemname=", we assign systemname to the section after the equal sign
if [[ $line =~ ^systemname= ]]; then systemname=$(echo $line | awk -F "=" '{print $2}'); fi
if [[ $line =~ ^directory= ]]; then directory=$(echo $line | awk -F "=" '{print $2}'); fi
#etc...
#The MODEn_NAME section will take a bit more work, if we're expected to handle an unknown number of inputs.
if [[ $line =~ ^MODE[0-9]*_NAME= ]]; then
#The following extracts the number, and saves it to $index
index=$(echo $line | awk -F "=" '{print $1}' | grep -o '[0-9]\+')
#Now we insert the text after the equal sign into an array element specified by the number
modename[$index]=$(echo $line | awk -F "=" '{print $2}')
#We could have saved some code by simply adding to the next available index,
#But then if a user entered the same mode number twice, we'd have a duplicate
fi
done< "blocka.txt"
dates=$(echo $directory | cut -d'/' -f12) #-f12 indicates '24_july
#Since we have an unknown number of modename indexes (and not necessarily in order),
#we will use a for loop to go through them.
for i in "${!modename[*]}"; do
filelist="$filelist"" MODE""$i""_NAME.xls"#This will be used at the end
#Edit: cp "$directory/mode""$i""/consolidate_full_file/file.mode""$i""/output_mode1/file.html" .
#As far as I can tell, each MODEn_NAME entry contains the full directory of each file. Which means you really don't need the $directory from before.
cp "$modename$i" .
mv "file.html" "MODE""$i""_NAME.xls" #See note below
done
echo "Sending files of $systemname on $dates" | mailx -s "Test" -a "$filelist" mmaz@hotmail.com
对于那个移动命令,你真的不需要它;您可以首先使用先前的cp
命令复制到该名称。但我把它包括在内以说明我做了什么,但没有改变。