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")
再次感谢大家,你的所有输入对新手来说非常有用!
答案 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
脚本以包含所有行而不是仅连接列,并在文件名包含任何将导致引号的内容时删除开始和结束引号。