如何在Bash命令中复用ANSI-C引用格式的变量?
问题描述
我需要将包含ANSI-C引用格式的字符串变量作为参数在后续Bash命令中复用,该变量存储的是一个文件列表(实际可为任意列表)。
比如我有test.lst文件,内容如下:
$ cat test.lst a.txt b.txt c.txt
我先将文件内容读入变量并转换为ANSI-C引用格式:
test_str=$(cat test.lst) test_str=${test_str@Q}
执行后得到的结果符合预期:
$ echo $test_str $'a.txt\nb.txt\nc.txt'
但将这个变量用于for循环时,无法得到期望的逐行输出:
$ for str in $test_str; do echo $str; done $'a.txt\nb.txt\nc.txt'
尝试用${test_str@E}反向扩展,结果却保留了开头的$'和结尾的',而且换行变成了空格:
$ str=${test_str@E} $ echo $str $'a.txt b.txt c.txt'
试过printf等方法都无效,请问如何在Bash命令中正确使用这类ANSI-C引用变量?
解决方案
方法1:用eval解析后循环读取
如果变量已经是ANSI-C引用格式,可通过eval解析转义字符,再用循环逐行处理:
eval "printf '%s\n' $test_str" | while read -r line; do echo "$line" done
eval会将$test_str中的\n解析为实际换行,再通过管道传给while read逐行读取,输出结果与原文件一致。
方法2:用数组存储列表(推荐)
若只是为了存储并复用列表,无需提前转换为ANSI-C格式,直接用数组更可靠:
# 从文件读取每行内容到数组 mapfile -t test_arr < test.lst # 遍历数组元素 for str in "${test_arr[@]}"; do echo "$str" done
数组是Bash处理列表的最优方式,能避免特殊字符(空格、换行等)导致的解析问题,后续复用更直观。
方法3:手动解析ANSI-C格式字符串
若必须保留ANSI-C格式变量,可先清除格式包裹符号,再解析转义序列:
# 去掉首尾的$'和' clean_str=$(sed "s/^\$'\(.*\)'$/\1/" <<< "$test_str") # 解析转义字符并逐行输出 printf '%b\n' "$clean_str" | while read -r line; do echo "$line" done
sed负责移除ANSI-C格式的外层标记,printf '%b'会解析字符串中的转义字符(如\n),还原为实际换行。
内容的提问来源于stack exchange,提问作者openBrain
相关产品推荐
相关产品推荐

