ファイルの指定されたオフセットに行を印刷します。

ファイルの指定されたオフセットに行を印刷します。

1行に50文字、合計50行のファイルがあります。ファイルの各行には文字が含まれています。文字のシリアル番号(52など)を指定し、指定され*た文字の前に適切な文字行を印刷したいと思います。

答え1

仕様をハードコードする1つの方法は、オフセット(改行を無視)に基づいて行と列番号を計算し、この値を使用して正しい行を選択し、正しい列を強調表示することです。

入力ファイルにはin50行があり、次のようになります。

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への最初の呼び出しは正しい行を選択し、2番目の呼び出しは*正しい列に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

関連情報