파일의 지정된 오프셋에 줄 인쇄

파일의 지정된 오프셋에 줄 인쇄

각 줄에 50자, 50줄로 구성된 파일이 있습니다. 파일의 각 줄에는 임의의 문자가 포함되어 있습니다. 문자 시퀀스 번호(예: 52)를 지정하고 *해당 문자 앞에 가 인쇄되도록 적절한 문자 줄을 인쇄하고 싶습니다 .

답변1

사양을 하드코딩하는 한 가지 방법은 오프셋(개행 무시)에서 줄과 열 번호를 계산하고 해당 값을 사용하여 적절한 줄을 선택하고 적절한 열을 강조 표시하는 것입니다.

입력 파일을 사용하면 in다음과 같이 50줄이 됩니다.

00ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
01ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
02ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
03ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
04ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv

그러면 다음 스크립트는 귀하가 요청한 것과 비슷한 작업을 수행해야 합니다.

while read -p '> ' n; do
    n=$((n - 1))
    line=$((n / 50 + 1))
    col=$((n % 50))
    <in sed -n -e "${line}p" | sed "s/^.\{${col}\}/&*/g"
done

상호작용 예시:

> 1
*00ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
> 2
0*0ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
> 49
00ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst*uv
> 50
00ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstu*v
> 52
0*1ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
> 125
02ABCDEFGHIJKLMNOPQRSTUV*WXYZabcdefghijklmnopqrstuv

sed에 대한 첫 번째 호출은 적절한 행을 선택하고, 두 번째 호출은 *적절한 열에 a를 삽입합니다.

답변2

linemod50(){
        dd bs=51 skip="$(($1/50))" count=1 | {
            dd bs=1 count="$(($1%50-!!($1%50)))"
            IFS= read -r rem
            printf "*%s\n" "$rem"
        }   2 >/dev/null
    }
    i=      forty9=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW
    while   [ "$((i+=1))" -le 50 ]
    do      echo "$((i%10))$forty9"
    done    >file
    linemod50 478 <file

1+0 records in
1+0 records out
51 bytes (51 B) copied, 9.5153e-05 s, 536 kB/s
0abcdefghijklmnopqrstuvwxyz*ABCDEFGHIJKLMNOPQRSTUVW

dd오프셋을 직접 탐색하기 때문에 아마도 가장 효율적인 솔루션일 것입니다 . 그러나 와이드 문자에서는 작동하지 않으며 파이프 입력으로 인해 예상치 못한 결과가 발생할 수 있습니다.

C 로케일에서 검색 가능한 입력을 제공하는 탁월한 솔루션입니다.

답변3

GNU 또는 FreeBSD 사용 sed( -r확장 정규식 옵션의 경우):

이 스크립트는 줄과 문자 위치 모두의 시작 부분으로 래핑됩니다. 그렇게 하지 않으려면 해당 while줄을 주석 처리하거나 삭제하세요.

#! /bin/bash

for O in "$@" ; do
   while [[ "$O" -gt 50 ]] ; do O=$(( $O -50 )) ; done
   O1=$(( $O - 1 ))
   sed -r -n "$O s/^(.{$O1})(.*)/\1\*\2/ p" input.txt
done


$ for i in {1..50} ; do printf "%02i%s\n" "$i" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv" ; done > input.txt

$ ./offset.sh 3 10 52 100
03*ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
10ABCDEFG*HIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
0*2ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
50ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstu*v

관련 정보