파일에서 가장 긴 줄을 읽으려면 while 읽기 루프를 사용하시겠습니까?

파일에서 가장 긴 줄을 읽으려면 while 읽기 루프를 사용하시겠습니까?

인터넷 검색을 해봤지만 while 루프를 사용하여 줄을 읽는 스크립트를 찾을 수 없습니다. 막혔고 어디서부터 시작해야 할지 모르겠어요

문제는 다음과 같습니다. 표준 입력에서 텍스트 행을 읽기 위해 while 읽기 루프를 사용하는 bash 스크립트 Longline.sh를 작성하십시오. 스크립트는 지금까지 읽은 가장 긴 줄을 추적하고 입력 끝에 도달하면 해당 줄을 인쇄해야 합니다.

또한 질문에서 텍스트 줄이 포함된 파일을 입력하라는 메시지가 표시되면 해당 파일을 읽거나 텍스트 줄 자체를 입력할지 확실하지 않습니다.

감사합니다.KB

답변1

cuonglm의 링크에 따르면 bash루프는 피해야 합니다.

awk이러한 의미에서 다음 코드는 표준 Unix 도구를 사용하여 파일에서 가장 긴 줄의 길이를 가져오지만 bash반복은 하지 않습니다.

awk '{n=length($0)>n?length($0):n} END{print n}' file

길이를 얻는 대신 가장 긴 줄을 인쇄하려면 다음을 사용하십시오.

awk '{longest=length($0)>length(longest)?$0:longest} END{print longest}' 

답변2

나는 오랫동안 bash로 글을 쓰지 않았기 때문에 어떤 비판이라도 받아들일 것입니다. :) 내 해결책은 다음과 같습니다.

n=0
longest=""
while read line; do
    len=`echo $line | wc -m`
    if [ $len -ge $n ]; then
        n=$len
        longest=$line
    fi
done 

echo $longest

@cuonglm의 제안을 읽었지만 더 적은 수의 프로세스 호출로 이를 수행할 수 있는 방법이 생각나지 않습니다. 물론, 나는 제안에 열려있습니다.

마지막 질문에 관해서는 실제로 중요하지 않습니다. 스크립트는 사용자가 입력하는 줄이나 입력으로 사용되는 파일에 대해 작업할 수 있습니다.

답변3

한 줄에 하나씩 모든 줄 번호 목록을 얻을 수 있습니다. 첫 번째는 길이별로 정렬되고 두 번째는 가장 큰 것부터 시작하여 줄 번호별로 정렬됩니다.

</path/to/infile LC_ALL=C \
tr -c \\n 1|grep -n '.\|'|sort -t: -rnk2

방법은 매우 간단합니다. ewline 문자가 아닌 tr모든 입력 바이트를 1로 변환하고 입력의 모든 행 앞에 각 행의 번호를 추가한 다음 입력에 a를 추가한 다음 역순으로 2cd부터 시작합니다. 필드가 정렬됩니다. a로 구분된 줄의 끝까지. 따라서 가장 긴 문자열이 맨 위로 떠오릅니다.\ngrep -n:sort:

그러나 입력에 멀티바이트 문자가 포함되어 있으면 문자가 아닌 바이트로만 번호가 매겨진다는 점에 유의해야 합니다. 후자를 잘하는 것은 작은 문제가 아니다.(내가 아는 한).

그럼에도 불구하고 - ASCII 로케일에서 - 위의 내용은 매우 큰 입력의 경우에도 매우 빠릅니다. 완전한 솔루션이 되기 위해서는 다른 것이 거의 필요하지 않습니다.

f=/path/to/file
n=$(<"$f" tr -c \\n 1|grep -n '.\|'|sort -t: -rnk2|head -n1)
l=$(<"$f" head -n"${n%:*}"|tail -n1)
printf "Line #%s at #${#l} bytes. Its contents:\n%s\n" \
   "${n%:*} is (possibly tied-for) the longest in $f" "$l"

관련 정보