我有一个文件(称为文件),其中有许多行,每行之间都有一个空格,如下所示:
abc 123
def 456
ghi 789
我需要循环遍历并抓取每个字段来稍微处理一下文本。我一直尝试这样做:
for i in `cat file`
do
var1=`echo ${i} | cut -d" " -f1`
var2=`echo ${i} | cut -d" " -f2`
echo "var1: ${var1} and var2: ${var2}"
done
以下是我得到的输出:
var1: abc and var2: abc
var1: 123 and var2: 123
var1: def and var2: def
var1: 456 and var2: 456
var1: ghi and var2: ghi
var1: 789 and var2: 789
为了清楚起见,预期输出将是:
var1: abc and var2: 123
var1: def and var2: 456
var1: ghi and var2: 789
不确定为什么这不起作用。我该怎么做才能获得预期的输出?
答案1
#!/bin/bash
input="/root/test.txt"
while IFS=' ' read -r f1 f2
do
printf 'VAR1: %s VAR2: %s\n' "$f1" "$f2"
done <"$input"
答案2
@ddiser 有一个我想象中的可行的解决方案,但没有解释原因,我认为这就是问题所在。
答案是“cat file”的输出 - 即由空格和换行符分隔的字符串列表。
当 for 语句看到结果时,它使用空格字符作为分隔符 - 它是否像您期望的那样处理空格来处理换行符。为了证明这一点,您可以修改文件以使用空格以外的字符(例如逗号或竖线),然后更改 cut 命令上的分隔符,这样就可以了。如果您使用 cat file|tr ' ' '|' " 而不是“cat file”,您甚至可以使用相同的文件格式(这并不是说这是 cat 的适当用法,但它应该有效)
答案3
我尝试结合之前贡献者的意见,并使用您的一些格式。此外,我还对您的代码进行了现代化改造,您也应该在编码时更广泛地考虑这一点。如果您有任何问题,请告诉我。
while IFS= read -r line ; do
var1="$( printf '%b' "${line}" | cut -d " " -f1 )"
var2="$( printf '%b' "${line}" | cut -d " " -f2 )"
printf '%s\n' "var1: ${var1} and var2: ${var2}"
done < /path/to/your/file.txt
这会起作用,因为 read 将文件的每一行都发送到循环。您的版本不会起作用,因为 cat 会先将文件发送到循环而不先对其进行划分。
无论如何,正如您可能猜到的那样,还有许多其他方法可以完成同一件事,因此您真的可以从 bash 中的许多不同工具中进行选择来制定解决方案。