1

我有一些 bash 脚本已经在 Ubuntu 14.04 和 16.04 上运行了一年多。最近的一些 Ubuntu 更新破坏了 bash,我不知道如何解决这个问题。

例子:

#!/bin/bash
INPUT=myinput.txt
OUTPUT=myoutput.txt
ACTION1="0;"

cat $INPUT | while read LINE
do
printf "\t\"~${LINE}\"\t\t$ACTION1\n" >> $OUTPUT
done

然后我的脚本循环执行 printf 语句的文件,如下所示,但这是产生的输出

"~jetmo" 0;
"~spamme" 0;
"~baidu" 0;

myinput.txt 的示例内容

jetmon
spammen
baidu

包含小写 n 字符的输入行被删除??我是否错过了 bash 发生的一些重大变化,这在一周前开始发生,现在让我发疯。

我尝试将 #!/bin/bash 更改为 #!/bin/sh 并得到相同的结果。

还尝试了这种循环输入文件的方法,仍然得到相同的结果。

#!/bin/bash
INPUT=myinput.txt
OUTPUT=myoutput.txt
ACTION1="0;"
while read LINE
do
printf "\t\"~${LINE}\"\t\t$ACTION1\n" >> $OUTPUT
done < $INPUT

尝试使用回声从评论中提出建议

echo -e -n "\t\"~${LINE}\"\t\t$ACTION1\n" >> $OUTPUT

现在我得到这个输出

-e -n "~jetmo" 0;
-e -n "~spamme" 0;
-e -n "~baidu" 0;

运行 hexdump -C myinput.txt 给出这个输出

00000000  6a 65 74 6d 6f 6e 0a 73  70 61 6d 6d 65 6e 0a 62  |jetmon.spammen.b|
00000010  61 69 64 75 0a 0a                                 |aidu..|
00000016

还按照迈克尔的建议将所有变量名称更改为小写,但仍然得到相同的结果。

#!/bin/bash
input=myinput.txt
output=myoutput.txt
action1="0;"

cat $input | while read line
do
printf "\t\"~${line}\"\t\t$action1\n" >> $output
done

解决方案 谜团解开了

感谢大家,但https://stackoverflow.com/users/96588/l0b0把它钉在了头上。IFS=$'\n'我早些时候在我的剧本中有一个隐藏。

多亏了 Nahuel 和 Charles 的建议,我现在有了最终的、更好和更安全的 printf 格式,它正在 100% 工作……非常感谢你们。

#!/bin/bash
input=myinput.txt
output=myoutput.txt
action1="0;"
while IFS= read -r LINE
do
printf '\t"~%s"\t\t%s\n' "${LINE}" "$ACTION1" >> "$output"
done < $input1
4

3 回答 3

3

如果内部字段分隔符 ( $IFS) 包含以下字母,则可能会发生这种情况n

$ IFS=$' \t\nn' read line <<< foon
$ printf '%q\n' "$line"
foo

这是一个相当普遍的错误。这是正确的值:

$ printf '%q\n' "$IFS"
$' \t\n'

例子:

$ IFS=$' \t\n' read line <<< foon
$ printf '%q\n' "$line"
foon
于 2017-07-04T14:02:37.947 回答
1

使用 printf 插入字符串会更安全%s,例如,如果它可以包含%

printf "\t\"~%s\"\t\t%s\n" "${LINE}" "$ACTION1" >> $OUTPUT

编辑以下评论,在第一个参数中使用单引号,因为没有变量扩展

printf '\t"~%s"\t\t%s\n' "${LINE}" "$ACTION1" >> "$OUTPUT"
于 2017-07-04T13:58:23.793 回答
0

解决方案 谜团解开了

感谢大家,但https://stackoverflow.com/users/96588/l0b0把它钉在了头上。IFS=$'\n'我早些时候在我的剧本中有一个隐藏。

多亏了 Nahuel 和 Charles 的建议,我现在有了最终的、更好和更安全的 printf 格式,它正在 100% 工作……非常感谢你们。

#!/bin/bash
input=myinput.txt
output=myoutput.txt
action1="0;"
while IFS= read -r LINE
do
printf '\t"~%s"\t\t%s\n' "${LINE}" "$ACTION1" >> "$output"
done < $input1
于 2017-07-04T15:02:15.983 回答