if 문에서 grep

if 문에서 grep

파일 이름을 묻는 함수를 작성 중입니다. 그런 다음 입력이 알파벳 문자로 시작하는지 확인하고 그렇지 않은 경우 조건이 충족될 때까지 사용자에게 이름을 다시 묻는 메시지를 표시합니다. 또한 사용자가 경로를 입력하는 경우 추가 메시지를 제공합니다(이 할당의 목적에 따라 경로는 "/"가 있는 모든 항목임). 이것이 제가 겪고 있는 문제입니다...

이건 내 코드야...

#1) make a getname function that will prompt for filename
function getname(){
trap control_c SIGINT
local fname=$1;

#if there is no input prompt user for file name
if [ ! $1 ]; then
        read -p "Enter a file name: " fname;
fi;

#until grep is given a valid file name
until ( grep -E '^[a-zA-Z_]\w+$' <<< "$fname" > /dev/null 2>&1); do





        #this is were the error is
        if echo "$fname" | grep -E '/';





         then                           #this tests if fname is a file directory
        echo "Paths are not a legal file name.";
        fi;
        read -p "Enter a legal file name: " fname;
done
echo "$fname"
}

Until 루프의 if 문은 어떤 상황에서도 사용자에게 경로가 유효한 입력이 아니라는 메시지를 표시하지 않으며 오류를 생성하지도 않습니다. if 문에서 grep을 올바르게 구현하는 방법은 무엇입니까?

답변1

실제로 Fedora 26에서는 이 기능이 작동합니다. GNU bash, version 4.4.12(1)-release (x86_64-redhat-linux-gnu)이 함수는 경로가 제공되는지 계속 묻습니다. 출력을 봅니다.

[@host testing]$ getname
Enter a file name: ab/sav
ab/sav
Paths are not a legal file name.
Enter a legal file name: abc                    
abc
[@host testing]$

그러나 두 가지 작은 문제를 발견했습니다. 먼저 경로를 인쇄한 다음 다시 입력을 요청합니다. 이 문제는 grep -q명령문에서 스위치(조용함을 뜻하는 q)를 사용하여 해결할 수 있습니다 if(또한 적용되며 until, 그러면 출력 리디렉션이 더 이상 필요하지 않습니다). 둘째, 루프 내에서는 개별 문자가 항상 유효하지 않습니다 until. 이 문제는 \w+정규 표현식을 변경하여 해결할 수 있습니다 \w*.

답변2

grep명령문이 매우 커질 때까지는 단순화할 수 있습니다.

저는 다음과 같은 접근 방식을 제안할 수 있습니다.

until [ ! -z "$fname" ]; do
        read -p "Enter a legal file name: " fname
        grep -E '^[a-zA-Z_]\w+$' <<< "$fname" > /dev/null 2>&1

        #check exit code
        if [ $? -ne 0 ]; then
                echo "Paths are not a legal file name."
                fname=""
        fi
done

필요한 경우 Until 루프 내부에 다른 조건을 연결할 수 있습니다.

사용자를 위한 메시지를 처리하려면 read여러 명령을 제시하지 않고도 이 트릭을 사용할 수 있습니다.

fname=""
message_for_user="Enter a file name: "

until [ ! -z "$fname" ]; do
        read -p "$message_for_user" fname
        grep -E '^[a-zA-Z_]\w+$' <<< "$fname" > /dev/null 2>&1

        #check exit code
        if [ $? -ne 0 ]; then
                echo "Paths are not a legal file name."
                fname=""
                message_for_user="Enter a legal file name: "
        fi
done

출력은 다음과 같습니다:

Enter a file name: 1laha
Paths are not a legal file name.
Enter a legal file name:

첫 번째 줄과 세 번째 줄은 다릅니다.

답변3

if명령문에서 직접 정규식을 사용할 수 있습니다 .

if [[ $name  =~ ^[a-zA-Z] ]]

또는:

if [[ $name  =~ ^[:alpha:] ]]

관련 정보