Bash将反引号添加到字符串中

时间:2011-09-01 21:46:09

标签: bash

Bash继续在myStats线上添加一个“更正前的$”。我该如何摆脱它?

一点背景:我创建了一个脚本来循环遍历search.txt中给出的文件,以提供统计信息并将其输出到新文件中。它工作正常,但它打破了目录或文件中有空格的任何文件名,所以我需要在文件路径中添加引号。

由于某种原因,在文件路径中添加引号会在路径的开头创建一个`,使整个脚本无效。子串化$ correct没有帮助,`正在添加到myStats行。

for i in $(cat search.txt); do
    corrected=\"$( echo "$i" )\"
    echo $corrected
    myStats="`stat $corrected | awk '( NR == 1 ) {print $1 $2 $3 $4 $5 $6 $7 $8};\
        ( NR == 2 ) {print $1 $2};\
        ( NR == 4 ) {print $3 $4 $5 $6 " " $7 $8 $9 $10 };\
        ( NR == 6 ) {print $1 $2 " " $3};'`"
    echo $myStats >> "$myHostname"
done

来自search.txt的示例:

/var/lib/tomcat5/webapps/isp.bak/usa.css
/var/lib/tomcat5/webapps/isp.bak/validationFunctions.js

有人有什么想法吗?谢谢!

编辑: I0b0提供了一个很好的解决方案,我也从每个人那里了解了IFS。抱歉不包括输出,它完全让我不知所措。这是我更新的代码(现在更加浓缩),其功能是找到这些文件扩展名,以查看我需要在服务器上备份的内容。

#Get file name as hostnameFiles.txt
myHostname="$(hostname)Files.txt"

#Write initial information to file
uname -n > "$myHostname"
echo "Script run on: " >> "$myHostname"
date -u >> "$myHostname"
echo "" >> "$myHostname"

#For each line from find, run stat and pull relevant information.
while IFS= read -r; do
    #echo "$REPLY"
    echo "$(stat "$REPLY" | awk '( NR == 1 ) {print $1 $2 $3 $4 $5 $6 $7 $8};\
        ( NR == 2 ) {print $1 $2};\
        ( NR == 4 ) {print $3 $4 $5 $6 " " $7 $8 $9 $10 };\
        ( NR == 6 ) {print $1 $2 " " $3};')" >> "$myHostname"
done < <(find / -iname "*.css" -or -iname "*.html" -or -iname "*.java" -or -iname "*.js" -or -iname "*.jsp" -or -iname "*.php" -or -iname "*.pl" -or -iname "*.py" -or -iname "*.rb"  -or -iname "*.sql")

再次感谢大家,你的所有输入对新手来说非常有用!

2 个答案:

答案 0 :(得分:1)

您的字符串和变量引用存在大量语法/使用错误,可以轻松解决您已识别的问题。如果您想编辑您的问题,那么查看您获得的实际输入和错误输出会很有帮助。

无论如何,你需要在你的awk印刷语句中逃避"字符,即

savIFS=${IFS}
IFS=
for i in $(cat search.txt); do
    corrected=\"$( echo "$i" )\"
    echo $corrected
    myStats="$(
        stat "$corrected" \
        | awk '
        ( NR == 1 ) {print $1 $2 $3 $4 $5 $6 $7 $8};
        ( NR == 2 ) {print $1 $2};
        ( NR == 4 ) {print $3 $4 $5 $6 \" \" $7 $8 $9 $10 };
        ( NR == 6 ) {print $1 $2 \" \" $3}
        '
      )"   # end myStats
    echo "$myStats" >> "$myHostname"
done
IFS="${savIFS} ; unset savIFS

我还建议您在for循环中使用$(...)时用cat search.txt替换backtics命令替换。您正在使用$(...)其他几个地方,为什么不使用多行代码来帮助您。

我假设你不想丢失$myStats的格式,所以我用dbl-quotes包围了它。通常,所有变量引用(即$ correct)都应该用dbl-quotes包围。

很难确定我是否有这个权利,因为我没有时间在名称中创建带空格的测试文件并创建一个新的search.txt,但我很乐意与你合作运行此代码时出错。 ${IFS}可能是不必要的,但我的时间差不多已经用完了。

我希望这会有所帮助。

P.S。因为您似乎是新用户,如果您得到的答案可以帮助您,请记住将其标记为已接受,并且/或者给它一个+(或 - )作为有用的答案。

答案 1 :(得分:1)

这是一个简单的解决方案:

while IFS= read -r; do
    echo "$REPLY"
    echo "$(stat "$REPLY" | awk '( NR == 1 ) {print $1 $2 $3 $4 $5 $6 $7 $8};\
        ( NR == 2 ) {print $1 $2};\
        ( NR == 4 ) {print $3 $4 $5 $6 " " $7 $8 $9 $10 };\
        ( NR == 6 ) {print $1 $2 " " $3};')" >> "$myHostname"
done < search.txt

如果您想在没有临时search.txt文件的情况下执行此操作,只需替换最后一行done < <(find ...)

如果查看简单touch 'foo bar' && stat 'foo bar'的输出,则可以轻松解释文件名前的反引号 - 文件行在stat输出中引用。您应该修改awk脚本以包含所有行而不是仅连接列,并在文件名包含任何将导致引号的内容时删除开始和结束引号。