~へfile.txt
chicken sheep cow
tomato cucumber
banana
if
声明なし
while read -r column1 column2 column3; do
command
done < file.txt
ステートメントを使用すると、if
行に3つの列がある場合は何を行います。2つの列が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
ノート:
あなたの例では、1行目と2行目の末尾に複数のスペースが含まれていますが、read
すべての前後のスペース文字はデフォルトで削除されます。
入力に3つ以上の列が含まれている場合、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
またはの配列を使用して行うことができますksh
(実際に位置パラメータを維持したい場合にも便利です)。以下の例は for ですbash
(in の代わりに for または in を使用でき、ksh
もちろん行を変更することもできます)。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