在文件中指定偏移处打印一行

在文件中指定偏移处打印一行

我有一个文件,每行 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

相关内容