>我有一个脚本,我试图从清单文件中读取,将该清单中的DOS路径转换为UNIX路径,然后对这些文件进行操作。 这是我尝试调试的代码片段:
while read line
do
srcdir=$(printf '%s' "$line" | awk -F \ -v OFS=/ '{ gsub(/r|^[ t]+|[ t]+$/, "") } !NF { next } /^\\/ { sub(/^.*\prj\/, "\prj\") } { $1 = $1 } 1')
done < manifest.txt
我的输入文件如下所示:
$ cat manifest.txt
\servermountdirectory
当我调试我的小 shell 片段时,我得到以下内容:
+ read line
++ printf %s 'servermountdirectory
'
++ awk -F '' -v OFS=/ '{ gsub(/r|^[ t]+|[ t]+$/, "") } !NF { next } /^\\/ { sub(/^.*\prj\/, "\prj\") } { $1 = $1 } 1'
+ srcdir=servermountdirectory
所以。。。无论是在读取还是在printf,字符都被解释为转义字符 - 我该如何解决这个问题?
注意。。。我知道我可以在尴尬中运行while
循环......问题是,在我的真实程序中,我在while
循环中还有其他需要用"$srcdir"
完成的事情——为此,sh是正确的工具...... 所以我真的需要一个解决方案。
从 posix 读作:
缺省情况下,除非指定 -r 选项,否则<反斜杠>应充当转义字符。未转义的<反斜杠>应保留以下字符的文本值,但<换行符除外>。如果<换行符>跟在<反斜杠后面>则读取实用程序应将其解释为行延续。<反斜杠>和<换行符>在将输入拆分为字段之前应被删除。将输入拆分为字段后,应删除所有其他未转义的<反斜杠>字符。反斜杠>换行符>反斜杠>反斜杠后面>换行符>换行符除外>反斜杠>反斜杠>
和:
-r
不要以任何特殊方式对待字符。将每个都视为输入行的一部分。
只:
while read -r line; do
另请记住,如果没有IFS=
,这将不会保留尾随和前导空格。
记住要始终做read -r
.这是一个很好的阅读: bashfaq 如何逐行(和/或逐字段)读取文件(数据流、变量)?。
还要记住,逐行读取文件在 bash 中效率非常低。最好使用命令、工具、流和管道处理整个文件。如果必须逐行读取文件,让"预处理"阶段解析整个文件,然后逐行读取:
awk .... manifest.txt |
while read -r srcdir; do
echo "$srcdir"
done
或者使用命令重定向,如果您需要循环在同一 shell 中运行:
while read -r srcdir; do
echo "$srcdir"
done < <(awk ... manifest.txt)