공백 없이 출력 문자열에서 변수 이름을 구분합니다.

공백 없이 출력 문자열에서 변수 이름을 구분합니다.

내가 원하는 코드 조각은 다음과 같습니다.

루프를 5번 반복합니다.
각 반복에서 다음 줄을 가져와야 합니다. 해당
줄을 파일의 시작
부분에 추가합니다.
ping; 일부 문장을 인쇄하고 사용자에게 코드 진행 상황을 알립니다.

반복이 효과가 있었습니다.
sed 부분을 건너뛰면 모든 것이 잘 작동하지만 동일한 대상에 대해 ping을 5번 실행합니다.
호스트.txt 파일의 각 줄에는 핑하려는 IP 주소가 있습니다.

for ((i>=1;i<=5;i++))  
do  
sed -n "$i p" hosts.txt | read output  
    touch "$output.txt"  
    date >> "$output.txt"  
    printf "\nComeçando o teste de $output."  
    printf "\nTeste em andamento."  
    ping -c 10 -i 1 "$output" >> "$output.txt"  
done  

문제는 sed 구문에 문제가 있다는 것입니다. bash를 직접 시도하면 sed -n 1p hosts첫 번째 줄이 표시됩니다. 그러나 숫자가 $i여야 하기 때문에 p 앞에 $i를 넣으면 bash는 변수 i와 그 뒤에 인수 p를 더하는 대신 ip를 변수로 해석합니다.

어떻게 하면 이 동작을 수정하고 더 이상 문제를 일으키지 않을 수 있나요?

답변1

나는 당신이 bash를 사용하고 있다고 가정하고 있으므로 이것이 더 잘 작동할 것입니다:

for ((i=1;i<=5;i++))  
do  
    sed -n "$i p" hosts.txt | (
        read output  
        touch "$output.txt"  
        date >> "$output.txt"  
        printf "\nComeçando o teste de $output."  
        printf "\nTeste em andamento."  
        ping -c 10 -i 1 "$output" >> "$output.txt"  
    )
done 

문제는 bash대부분의 외부 쉘 인터프리터와 마찬가지로 ksh모든 파이프 구성 요소가 하위 쉘에 배치되므로 output변수가 설정되자마자 손실된다는 것입니다.

또한 변수가 초기화되지 않아 for정의되지 않은 동작이 발생한 루프를 수정했습니다 .i

답변2

보시다시피 문제는 및 둘 다 유효한 변수 이름이라는 i것 입니다. 따라서 문자 뒤에 오는 값을 ip사용하려면 중괄호를 사용하여 변수 이름이 시작하고 끝나는 위치를 명확하게 구분할 수 있습니다.$ip

sed -n "${i}p" hosts.txt | read output

답변3

약간 더 간단한 해결책은 다음과 같습니다.

for ((i=1; i<=5; i++))
do
    read output
    date >> "$output.txt"
    printf "\nComeçando o teste de %s." "$output"
    printf "\nTeste em andamento."
    ping -c 10 -i 1 "$output" >> "$output.txt"
done < hosts.txt

< hosts.txt마지막 줄 끝에 있는 을 참고하세요 done. 이렇게 하면 해당 줄이 한 번 열리고 hosts.txt그 안의 처음 5줄만 읽혀집니다. don_crissti가 언급했듯이 루프에서 이 작업을 수행한다는 것은 파일을 5번 sed … hosts.txt | read output 읽는다는 의미입니다 . 파이프라인이 아닌 루프의 나머지 부분과 평행하기 hosts.txt때문에 read output루프의 나머지 코드는 output파일에서 읽은 값에 액세스할 수 있습니다. 또한 (지적한 것처럼) touch;command>>filefile아직 존재하지 않는 경우.

파일 중 하나가 hostname.txt이미 존재하는 경우 이 코드는 해당 파일에 새 정보를 추가합니다. 이전 데이터를 버리고 처음부터 시작하려면 date > "$output.txt"대신 을 수행하십시오 date >> "$output.txt".

알 수 없는 데이터를 에 직접 전달할 때는 주의하세요 printf. 드물게 "호스트 이름" 중 하나가 포함되면 %코드에서 해당 이름이 왜곡될 수 있습니다. 외부 데이터를 %s(인쇄 문자열) 에 전달하는 것이 좋습니다 .

파일의 처음 다섯 줄만 읽고 hosts.txt중지할지, 아니면 전체 파일을 읽고 싶었는데 우연히 그 길이가 다섯 줄인지는 말하지 않았습니다. 전체 파일을 읽으려면 다음을 수행하십시오.

while read output
do
    date >> "$output.txt"
    printf "\nComeçando o teste de %s." "$output"
    printf "\nTeste em andamento."
    ping -c 10 -i 1 "$output" >> "$output.txt"
done < hosts.txt

파일 끝에 도달하면 명령문이 read output실패하고 루프가 종료됩니다.

관련 정보