`我有一个脚本,试图从清单文件中读取脚本,将该清单中的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
\\server\mount\directory
调试我的小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上,\
字符都被解释为转义字符-我该如何解决?
注意...我知道我可以在 awk 中运行while
循环...问题是,在我的真实程序中,{{1 }}循环,需要使用while
-为此, sh 是正确的工具...所以我真的需要 sh
答案 0 :(得分:1)
来自posix read:
默认情况下,除非指定了-r选项,否则<反斜杠>应充当转义字符。未经转义的<反斜杠>应保留以下字符的文字值,但
除外。如果<反斜杠>之后是 ,则read实用程序应将此解释为行继续。在将输入拆分为字段之前,应删除<反斜杠>和<换行符。将输入拆分为字段后,应删除所有其他未转义的<反斜杠>字符。
和:
-r
不要以任何特殊方式对待角色。将每个都视为输入行的一部分。
只是:
while read -r line; do
还请记住,如果没有IFS=
,将不会保留尾随和前导空格。
请记住始终执行read -r
。这是一本好书:bashfaq How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?。
还请记住,逐行读取文件在bash中效率很低。最好使用命令,工具,流和管道来处理整个文件。如果必须逐行读取文件,请让“预处理”阶段解析整个文件,然后逐行读取它:
awk .... manifest.txt |
while read -r srcdir; do
echo "$srcdir"
done
或使用命令重定向,如果您需要循环在同一shell中运行:
while read -r srcdir; do
echo "$srcdir"
done < <(awk ... manifest.txt)