我正在尝试使用 Bash 来完成欧拉计划 13。下面是我的代码,我就是不知道它哪里出了问题。
#!/bin/bash
sum=0
while read -r -d $'\r' line; do
sum=$(echo $sum + $line | bc)
done <<< "$(curl -s http://pastebin.com/raw/uHZ0PZjm)"
echo "${sum:0:10}"
exit
它曾经导致两个错误,
(standard_in) 1: syntax error
和
(standard_in) 1: illegal character: ^M
经过一番研究,这似乎是 EOF 终止符的问题。然后我在其上运行了 dos2unix,它不再给出第二个错误,但仍然重复给出第一个错误。这似乎是我将数据导入 bc 的方式存在一些问题,但我不知道该做什么或如何修复它。
正确答案是 5537376230。非常感谢您提供的任何帮助!
系统信息是
GNU bash,版本 4.3.11(1)-发布(x86_64-pc-linux-gnu)
我在 Windows 10 上使用 cmder。
答案1
您需要将 \n ( == 0x0a == LF == 换行符) 设置为read
分隔符,而不是\r
( == 0x0d == CR == 回车符)。要么这样,要么确保在 pastebin 文件末尾放置一个 CR。看起来您的 pastebin 文件在最后一行的末尾缺少行终止符序列,因此最后一行永远不会被输入到您的脚本中。
$ curl -s http://pastebin.com/raw/uHZ0PZjm | hexdump -C | tail -n 8
...(snip)...
000013e0 35 30 39 35 31 36 0d 0a 32 30 38 34 39 36 30 33 |509516..20849603|
000013f0 39 38 30 31 33 34 30 30 31 37 32 33 39 33 30 36 |9801340017239306|
00001400 37 31 36 36 36 38 32 33 35 35 35 32 34 35 32 35 |7166682355524525|
00001410 32 38 30 34 36 30 39 37 32 32 0d 0a 35 33 35 30 |2804609722..5350|
00001420 33 35 33 34 32 32 36 34 37 32 35 32 34 32 35 30 |3534226472524250|
00001430 38 37 34 30 35 34 30 37 35 35 39 31 37 38 39 37 |8740540755917897|
00001440 38 31 32 36 34 33 33 30 33 33 31 36 39 30 |81264330331690|
0000144e
请注意,每个数字之间都有一个 0x0d0a(CR LF),但最后一个数字之后没有。
$ while read -r -d $'\r' line; do echo $line; done <<< "$(curl -s http://pastebin.com/raw/uHZ0PZjm)" | tail -n 3
77158542502016545090413245809786882778948721859617
72107838435069186155435662884062257473692284509516
20849603980134001723930671666823555245252804609722
请注意,在运行命令时,最后一个数字 535[...]690 会丢失read
。但如果您将分隔符切换为 Unix 原生的 LF (\n) 换行符,则会包含最后一行:
$ while read -r -d $'\n' line; do echo $line; done <<< "$(curl -s http://pastebin.com/raw/uHZ0PZjm)" | tail -n 3
72107838435069186155435662884062257473692284509516
20849603980134001723930671666823555245252804609722
53503534226472524250874054075591789781264330331690
编辑后添加:以下是处理 pastebin 文件中 CR 的修复方法。我告诉read
使用 CRLF 作为分隔符,并使用额外的 echo 在 pastebin 文件后添加 CRLF。
sum=0
while read -r -d $'\r\n' line; do
sum=$(echo $sum + $line | bc)
done <<< $(curl -s http://pastebin.com/raw/uHZ0PZjm; echo -e "\r\n")
echo "${sum:0:10}"