我正在尝试编写一个bash脚本,该脚本应该找到其中包含特定字符串的文件。脚本调用另一个返回格式字符串的脚本:
url=titletitle是我要找的字符串。title可以有如下所示的值,例如:'A Soldier Of The Legion'。我试图在/tmp/audiobooks目录中找到包含标题'A Soldier Of The Legion'的文件。/tmp/audiobooks中的所有文件都有以AB.yaml结尾的名称。
下面是脚本:
#!/bin/sh
get_pairs='/home/me/util/scripts/get-pairs.sh'
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for i in `$get_pairs`
do
echo "pair $i"
url=`echo $i | cut -d= -f1`
apptitle=`echo $i | cut -d= -f2- | cut -c1-52`
echo "grep -l $apptitle /tmp/audiobooks/*AB.yaml | head -1"
the_file=$(grep -l $apptitle /tmp/audiobooks/*AB.yaml | head -1)
echo "the_file=$the_file"
if [ -z $the_file ]
then
echo "No hiera file found for $apptitle ... skipping"
continue
fi
appname=`basename $the_file .yaml`
echo "url is[$url] and apptitle is [$apptitle] appname is [$appname]"
exit 0
done
IFS=$SAVEIFS脚本产生的输出如下:
pair http://www.example.com/product/B06XK9FGYD='A Soldier Of The Legion'
grep -l 'A Soldier Of The Legion' /tmp/audiobooks/*AB.yaml | head -1
the_file=
No hiera file found for 'A Soldier Of The Legion' ... skipping
pair http://www.example.com/product/B01GWQI0OS='Art of War Sun Tzu'
grep -l 'Art of War Sun Tzu' /tmp/audiobooks/*AB.yaml | head -1
the_file=
No hiera file found for 'Art of War Sun Tzu' ... skipping
pair http://www.example.com/product/B0717333MM='Bartleby, the Scrivener (version 2)'
grep -l 'Bartleby, the Scrivener (version 2)' /tmp/audiobooks/*AB.yaml | head -1
the_file=/tmp/audiobooks/BartlebyTheScrivener_AMZAD_AB.yaml
url is[http://www.example.com/product/B0717333MM] and apptitle is ['Bartleby, the Scrivener (version 2)'] appname is [BartlebyTheScrivener_AMZAD_AB]奇怪的是,当我从命令行运行每个grep命令时,我响应它们的工作.例如:
$ grep -l 'A Soldier Of The Legion' /tmp/audiobooks/*AB.yaml | head -1
/tmp/audiobooks/A_Soldier_of_the_Legion_AB.yaml该脚本适用于标题'Bartleby, the Scrivener (version 2)'。
发布于 2017-07-02 04:28:51
如果这一行:
echo "grep -l $apptitle /tmp/audiobooks/*AB.yaml _ head -1“
产生这样的输出:
grep -l‘军团战士’/tmp/有声读物/*AB.yaml_ head -1
这意味着apptitle的值包含单引号。
你可以试试这个来理解发生了什么:
value1='A Soldier Of The Legion'
value2="'A Soldier Of The Legion'"
echo "$value1"
echo "$value2"产出:
A Soldier Of The Legion
'A Soldier Of The Legion'换句话说,脚本真正执行的是:
grep -l "'A Soldier Of The Legion'" /tmp/audiobooks/*AB.yaml | head -1只有当yaml文件包含由单引号包围的标题时,才会匹配。
例如,您可能希望删除apptitle中的单引号:
apptitle=$(echo $i | cut -d= -f2- | cut -c1-52 | sed -e "s/^'//" -e "s/'$//")上面的sed将去掉两端的单引号,并将其他单引号单独放在字符串的中间。
发布于 2017-07-02 04:29:57
$apptitle包含标题周围的开始和结束单引号(')字符,您的脚本将它们传递给grep。
grep。这就是说,您的脚本没有运行您希望它运行的相同的grep命令。.yaml文件在搜索的标题周围有单引号,脚本将适用于这些文件。但这对其他人不起作用。(我想这就是你的一个头衔的工作机会。)从您的问题的早期编辑历史来看,您可能已经考虑过这种可能性,并试图通过更改来防止这种可能性。
the_file=$(grep -l "$apptitle" /tmp/audiobooks/*AB.yaml | head -1)改为:
the_file=$(grep -l $apptitle /tmp/audiobooks/*AB.yaml | head -1)不会有帮助的。'还在那里。(我建议取消这一更改,但由于您分配了IFS的值,这很可能是可以的。)
当引用字符(如' )出现在参数展开($apptitle)的结果中时,shell不对其进行特殊处理。它不能阻止分词,也不受移除引号的制约。
例如,当IFS有其默认值时,x="'a b c'"; printf '(%s)' $x的输出是('a)(b)(c'),而不是(a b c)。这就是说,当x持有'a b c'值时,未引用的$x扩展为'a b c',而分词将其转化为'a b c'。
在您的例子中,您已经更改了IFS,因此拆分只发生在换行符和后置空间上。grep与行匹配,所以标题中不会出现换行符。假设标题永远不包含后置空间,保持$apptitle不被引用是很好的(尽管可能在风格上令人困惑)。但这并不会删除'字符。
发布于 2017-07-02 03:31:16
我认为在执行. ( get-pairs.sh )时需要放置get-pairs.sh(点)。前面的点意味着将该文件的内容“源”到当前的shell中。
for i in `. $get_pairs`https://stackoverflow.com/questions/44867115
复制相似问题