입력 파일 라인의 루프에서 마지막 반복을 표시하는 방법이 있습니까?

입력 파일 라인의 루프에서 마지막 반복을 표시하는 방법이 있습니까?

direction다음 줄이 포함된 파일이 있다고 가정해 보겠습니다.

east
north
south
west
south-west

루프를 사용하고 echo쉘 스크립트에서 다음 출력을 생성합니다.

Direction: east
Direction: north
Direction: south
Direction: west
Last direction: south-west

즉, 스크립트의 마지막 줄에서 다른 작업을 수행하고 싶습니다.

답변1

bash파일의 끝을 감지할 수 있는 방법은 없지만(다음 줄을 읽으려고 시도하지 않고 실패함) Perl은 해당 eof기능을 사용할 수 있습니다.

$ perl -n -e 'print "Last " if eof; print "Direction: $_"' direction 
Direction: east
Direction: north
Direction: south
Direction: west
Last Direction: south-west

참고: echoBash와 달리 Perl의 명령문은 1. 인쇄할 문자열에 포함하여 명시적으로 지정하거나 2. Perl의 명령줄 옵션을 사용하거나 3. 문자열에 새 줄 포함...이 있는 경우를 print제외하고는 줄 바꿈을 인쇄하지 않습니다 . - 의 경우이므로 개행 문자를 제거하는 데 자주 필요합니다.\n-l$_chomp()

Perl에서 BTW는 $_현재 입력 라인입니다. 또는 실제 변수 이름을 지정하지 않는 루프의 기본 반복자(종종 "현재 항목"이라고 함)많은$_제공되지 않으면 Perl 함수 및 연산자가 기본/암시적 매개변수로 사용됩니다. 보기 man perlvar$_검색

sed또한 작동합니다. $주소는 파일의 마지막 줄과 일치합니다.

$ sed -e 's/^/Direction: /; $s/^/Last /' direction 
Direction: east
Direction: north
Direction: south
Direction: west
Last Direction: south-west

규칙의 순서가 sed중요합니다. 나의 첫 번째 시도는 잘못된 방향으로 진행되었습니다(그리고 "방향: 마지막 남서쪽"이 인쇄되었습니다). 이 sed 스크립트는 항상 각 줄의 시작 부분에 "Direction:"을 추가합니다. 마지막 줄( $)에서는 이전 문에 의해 수정된 줄의 시작 부분에 "Last"를 추가합니다.

답변2

루프는 실제로 끝에 도달하지 않는 한 언제 끝에 도달했는지 알 수 없습니다. 따라서 파일을 두 번 처리합니다. 한 번은 줄 수를 얻고 다른 번은 출력할 때를 처리하거나 각 반복에서 이전 값을 인쇄하고 루프를 종료할 때 마지막 값을 인쇄합니다.

prev=""
while read direction; do 
    if [ -n "$prev" ]; then 
        echo "Direction: $prev"
    fi
    prev="$direction"
done < direction
echo "Last Direction: $prev" 

답변3

의 변종FelixJN의 답변, 행을 배열로 읽지만 bash 루프 대신 bash 내장을 사용합니다.

mapfile -t DIR < direction
printf "Direction: %s\n" "${DIR[@]::${#DIR[@]}-1}"
printf "Last direction: %s\n" "${DIR[-1]}"

지도 파일표준 입력을 항목당 한 줄씩 배열로 읽는 Bash 4에 추가된 내장 함수입니다. 이 -t옵션은 개행 문자를 제거합니다.

printf해당 형식 문자열은 모든 입력 매개변수가 소진될 때까지 반복적으로 적용됩니다.

답변4

paste, tail및 다음을 혼합할 수 있습니다 head.

$ paste -s -d'\n' <(head -n -1 direction | sed 's/^/Direction: /') <(tail -n1 direction | sed 's/^/Last direction: /')
Direction: east
Direction: north
Direction: south
Direction: west
Last direction: south-west

  • paste -s -d'\n'-d'\n'옵션 및 옵션과 함께 개행 문자를 구분 기호로 사용하십시오 -s.

    -s, --serial
    병렬 대신 한 번에 하나의 파일을 붙여넣습니다.

  • head -n -1마지막 줄과 파이프를 제외한 모든 줄을 검색하여 sed해당 줄에만 필요한 명령을 실행합니다.

  • tail -n1 file파일의 마지막 줄을 검색하고 파이프하여 sed해당 줄에 필요한 명령만 실행합니다.


또는 더 간결하게 cat대신 사용하십시오 paste.@MickMatteo의 코멘트:

$ cat <(head -n -1 direction | sed 's/^/Direction: /') <(tail -n1 direction | sed 's/^/Last direction: /')

관련 정보