假设$file
保存文件名的值,例如Dr' A.tif
.在 bash 编程中,如何在$file
不删除特殊字符的情况下转义单引号和任何其他特殊字符?
2014 年 7 月 9 日更新
作为来自@Gilles 的请求,以下代码片段无法处理Dr' A.tif
:
files=$(find /path/ -maxdepth 1 -name "*.[Pp][Dd][Ff]" -o -name "*.[Tt][Ii][Ff]")
echo "${files}" > ${TEMP_FILE}
while read file
do
newfile=$(echo "${file}" | sed 's, ,\\ ,g') ## line 1
done < ${TEMP_FILE}
在我尝试过之后@Patrick 的回答上line 1
,它似乎对我有用。但是,如果我有诸如 之类的文件Dr\^s A.tif
,printf
命令似乎没有帮助,它会向我显示Dr\^s\ A.tif
。如果我像这样在控制台上手动尝试:
printf "%q" "Dr\^s A.tif"
我将得到这个输出:
Dr\\\^s\ A.tif
知道如何处理这个问题吗?
答案1
您可以使用printf
内置的 with%q
来完成此操作。例如:
$ file="Dr' A.tif"
$ printf '%q\n' "$file"
Dr\'\ A.tif
$ file=' foo$bar\baz`'
$ printf '%q\n' "$file"
\ foo\$bar\\baz\`
从 bash 文档中printf
:
In addition to the standard format specifications described in printf(1) and printf(3), printf interprets: %b expand backslash escape sequences in the corresponding argument %q quote the argument in a way that can be reused as shell input %(fmt)T output the date-time string resulting from using FMT as a format string for strftime(3)
答案2
尝试:-
file=Dr\'\ A.tif
echo $file
Dr' A.tif
或者
file="Dr' A.tif"
echo $file
Dr' A.tif
或者如果字符串包含双引号:-
file='Dr" A.tif'
echo $file
Dr" A.tif
网上有关于转义和引用的很好的教程。从...开始这个。
答案3
您不需要转义脚本中正在处理的任何文件名。仅当您想将文件名作为文字在脚本中,或将多个文件名作为单个输入流传递给另一个脚本。
由于您正在循环遍历 的输出find
,这是最简单的方法之一(!)处理每条可能的路径:
while IFS= read -r -d ''
do
file_namex="$(basename -- "$REPLY"; echo x)"
file_name="${file_namex%$'\nx'}"
do_something -- "$file_name"
done < <(find "$some_path" -exec printf '%s\0' {} +)
答案4
如果没有额外的操作,这些答案中的许多答案(包括使用 的投票最高的答案printf "%q"
)将无法在所有情况下起作用。我建议如下(示例如下):
cat <<EOF
2015-11-07T03:34:41Z app[postgres.0000]: [TAG] text-search query doesn't contain lexemes: ""
EOF