while 루프와 if 문은 조건이 충족되면 서로 다른 명령을 실행합니다.

while 루프와 if 문은 조건이 충족되면 서로 다른 명령을 실행합니다.

~에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또는 의 배열을 사용하여 수행할 수 있습니다 ksh(실제로 위치 매개변수를 유지하려는 경우에도 편리합니다). 아래 예는 for입니다 bash(in 대신 for 또는 in을 사용할 수 있으며 ksh물론 줄을 변경할 수도 있습니다).mksh-A-aread#!

#!/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

관련 정보