我有一个文件名/tmp/urlFile
,其中每一行代表一个URL。我正在尝试从文件中读取内容,如下所示:
cat "/tmp/urlFile" | while read url
do
echo $url
done
如果最后一行不以换行符结尾,则不会读取该行。我想知道为什么?
是否可以读取所有行,而不管它们是否以新行结尾?
awk 1 /tmp/urlFile
.. soawk 1 /tmp/urlFile | while ...
我有一个文件名/tmp/urlFile
,其中每一行代表一个URL。我正在尝试从文件中读取内容,如下所示:
cat "/tmp/urlFile" | while read url
do
echo $url
done
如果最后一行不以换行符结尾,则不会读取该行。我想知道为什么?
是否可以读取所有行,而不管它们是否以新行结尾?
awk 1 /tmp/urlFile
.. soawk 1 /tmp/urlFile | while ...
Answers:
您可以:
while IFS= read -r url || [ -n "$url" ]; do
printf '%s\n' "$url"
done < url.list
(实际上,该循环将丢失的换行符添加回最后(非)行)。
也可以看看:
printf
此处的所有调用都具有,所以它将在输出中添加缺少的换行符\n
。
这似乎可以通过以下方式部分解决readarray -t
:
readarray -t urls "/tmp/urlFile"
for url in "${urls[@]}"; do
printf '%s\n' "$url"
done
但是请注意,尽管这确实适用于大小合理的文件,但此解决方案会给大型文件带来潜在的新问题-它首先将文件读取到数组中,然后必须对其进行遍历。对于非常大的文件,这可能既浪费时间又消耗内存,甚至可能导致故障。
根据定义,文本文件由一系列行组成。甲线以换行符结束。因此,文本文件以换行符结尾,除非为空。
该read
内建只是为了阅读的文本文件。您没有传递文本文件,因此您不能希望它无缝运行。Shell会读取所有行-跳过的是最后一行之后的多余字符。
如果您有一个可能格式错误的输入文件,可能缺少最后一行,则可以确保在其中添加换行符。
{ cat "/tmp/urlFile"; echo; } | …
Windows编辑器通常会生成应为文本文件但缺少最后换行符的文件。这通常与Windows行尾CR LF结合使用,与Unix的LF相反。CR字符很少在任何地方有用,并且在任何情况下都不会出现在URL中,因此应将其删除。
{ <"/tmp/urlFile" tr -d '\r'; echo; } | …
如果输入文件格式正确且以换行符结尾,则echo
添加额外的空白行。由于网址不能为空,因此只需忽略空白行。
还请注意,read
这不会以直接的方式读取行。它忽略前导和尾随空格,这对于URL可能是理想的。它将行尾的反斜杠视为转义字符,导致下一行与第一行(减去反斜杠-换行符)连接在一起,这绝对是不希望的。因此,您应该将-r
选项传递给read
。read
做对而不是做是非常非常少的read -r
。
{ <"/tmp/urlFile" tr -d '\r'; echo; } | while read -r url
do
if [ -z "$url" ]; then continue; fi
…
done
好吧,read
如果它在换行符之前遇到文件结尾,则返回一个伪造的值,但是即使这样做,它仍然会分配它读取的值。因此,我们可以检查最终的return是否read
返回空行以外的其他内容,并按正常方式进行处理。因此,只有在read
返回false 且该行为空之后才退出循环:
#!/bin/sh
while IFS= read -r line || [ "$line" ]; do
echo "line: $line"
done
$ printf 'foo\nbar' | sh ./read.sh
line: foo
line: bar
$ printf 'foo\nbar\n' | sh ./read.sh
line: foo
line: bar
猫“ / tmp / urlFile” | 同时读取网址 做 回声$ url 做完了
这是的无用用法cat
。
具有讽刺意味的是,您可以在cat
这里用实际上有用的东西代替该过程:POSIX系统具有的一种工具,用于添加缺少的换行符,并将该文件制作为正确的POSIX文本文件。
sed -e'$ a \'“ / tmp / urlFile” | 同时读取-r url 做 printf“%s \ n”“ $ {url}” 做完了
read
也会指定行为。