我想处理包含单引号文件名的文本文件中的文件,例如
'new'$'\n''line'
'tab'$'\t''ulator'
copy&用于手动处理此文件的粘贴工作正常:
test -f 'tab'$'\t''ulator'
现在,用bash读取文件读取内置命令
while IFS="" read -r myfile; do
line=$myfile
...
done < text.txt
提供包含转义单引号的字符串,例如
'\''new'\''$'\''\n'\'''\''line'\'''
'\''tab'\''$'\''\t'\'''\''ulator'\'''
但是,在bash脚本中处理此文件名不起作用。
test -f "$myfile"
test -f ${myfile}
如何禁用/撤消转义单引号并在bash中处理原始文件名?
答案 0 :(得分:2)
eval
许多人非常合理地考虑eval
as a mis-spelling of evil。
所以,我认为这个解决方案只有在其他所有方法都失败时才能使用。
我们来看看这个样本文件:
$ cat badformat
'new'$'\n''line'
'tab'$'\t''ulator'
我们可以阅读和解释这些文件名,如下例所示:
while read -r f; do
eval "f=$f"; [ -f "$f" ] || echo "file not found"
done <badformat
不能在Unix文件名中的唯一字符是NUL(十六进制00)。因此,许多Unix工具被设计为能够处理NUL分离的列表。
因此,在创建文件时,请替换:
stat -c %N * >badformat
使用:
printf '%s\0' * >safeformat
后一个文件可以通过while-read循环读入shell脚本。例如:
while IFS= read -r -d $'\0' f; do
[ -f "$f" ] || echo "file not found"
done <safeformat
除了shell while-read循环外,请注意grep
,find
,sort
,xargs
以及GNU sed
和GNU { {1}},都具有处理NUL分隔列表的本机能力。因此,NUL分离列表方法既安全又受到良好支持。
答案 1 :(得分:0)
找到了使用字符串操作的解决方案
${filename//$'\047'\\$'\047'$'\047'/$'\047'}
如上所述,使用eval对文件名非常危险,例如&rm -rf&#39;。关于stat -c%N(只转义单引号,换行符和制表符)还有另一个解决方案
while IFS="" read -r myfile; do
filename="$myfile"
filename="${filename#?}"
filename="${filename%?}"
filename="${filename//"'$'\t''"/$'\011'}"
filename="${filename//"'$'\n''"/$'\012'}"
filename="${filename//$'\047'\\$'\047'$'\047'/$'\047'}"
test -f "$filename" && echo "$myfile exists"
done < text.txt