里面file.txt
chicken sheep cow
tomato cucumber
banana
无if
声明
while read -r column1 column2 column3; do
command
done < file.txt
使用if
语句,如果该行有三列,它会做什么command1
,如果它有两列,它会做什么command2
,如果只有一列,它会做什么command3
?
答案1
或者其他方法与您的示例差异最小:
#!/bin/bash
while read -r column1 column2 column3; do
if [ -z "$column2" ] ; then
printf '%s\n' "Only first column has data"
elif [ -z "$column3" ]; then
printf '%s\n' "Only first and second columns has data"
elif [ -n "$column3" ]; then
printf '%s\n' "All three columns has data"
fi
done < file.txt
输出将是:
All three columns has data
Only first and second columns has data
Only first column has data
笔记:
在您的示例中,第一行和第二行末尾包含多个空格,但默认情况下read
会删除所有前导和尾随空格字符。
如果您的输入包含超过 3 列,则第三列及后续列中的所有数据将放置在column3
答案2
您可以使用 将每一行读入数组read -ra
,然后检查数组大小:
fmt="Number of fields: %s. The last one: %s\n"
while read -ra items; do
if [ ${#items[*]} == 3 ]; then
printf "$fmt" ${#items[*]} ${items[-1]}
elif [ ${#items[*]} == 2 ]; then
printf "$fmt" ${#items[*]} ${items[-1]}
elif [ ${#items[*]} == 1 ]; then
printf "$fmt" ${#items[*]} ${items[-1]}
fi
done < file.txt
当然,表达式printf "$fmt" ${#items[*]} ${items[-1]}
只是为了演示,你可以自己定义。
上述方法输出(作为示例):
Number of fields: 3. The last one: cow
Number of fields: 2. The last one: cucumber
Number of fields: 1. The last one: banana
答案3
while read -r column1 column2 column3; do
if [ -z "$column2" ]; then
# one column
: command
elif [ -z "$column3" ]; then
# two columns
: command
else
# three columns
: command
fi
done < file.txt
或者
while read -r column1 column2 column3; do
set -- $column1 $column2 $column3
case $# in
1)
: command
;;
2)
: command
;;
*)
: command
;;
esac
done < file.txt
答案4
豪克·拉金的回答已经有了通过设置位置参数并在每次迭代中评估其数量来使用评估的好主意。主题的变化可以通过使用bash
or中的数组来完成ksh
(如果我们确实想保留位置参数,这也很方便)。下面的示例是 for bash
(请注意,您可以使用forksh
或in 代替in ,当然还要更改行):mksh
-A
-a
read
#!
#!/usr/bin/env bash
line_counter=1
while read -r -a arr;
do
case "${#arr[@]}" in
1) printf "One column in line %d\n" "$line_counter";;
2) printf "Two columns in line %d\n" "$line_counter";;
3) printf "Three columns in line %d\n" "$line_counter";;
*) printf "More than 3 lines in line %d\n" "$line_counter";;
esac
((line_counter++))
done < input.txt
输出如下:
$ ./eval_columns.sh
Three columns in line 1
Two columns in line 2
One column in line 3