Imprimindo uma linha em um deslocamento especificado em um arquivo

1

Eu tenho um arquivo com 50 caracteres em cada linha e 50 linhas. Cada linha do arquivo contém letras arbitrárias. Quero especificar um número de seqüência de caracteres (ex: 52) e ter a linha de letras apropriada impressa com um * impresso na frente do caractere fornecido.

    
por littlemisschik 03.11.2015 / 18:08

3 respostas

0

Codificando suas especificações, uma maneira seria calcular a linha e números de coluna do deslocamento (ignorando as novas linhas) e use valores para selecionar a linha apropriada e destacar a coluna apropriada.

Com um arquivo de entrada in que são 50 linhas assim:

00ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
01ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
02ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
03ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
04ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv

Em seguida, o script a seguir deve fazer aproximadamente o que você pediu:

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

Exemplo de interação:

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

A primeira chamada para sed seleciona a linha apropriada, a segunda insere um * na coluna correta.

    
por 03.11.2015 / 19:22
0
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

É provavelmente a solução mais eficiente porque dd apenas procurará diretamente no seu deslocamento. No entanto, ele não funciona com caracteres largos e pode produzir resultados inesperados com entrada canalizada.

É uma excelente solução com entrada procurada na localidade C.

    
por 03.11.2015 / 19:23
0

Usando o GNU ou FreeBSD sed (para a opção de expressão regular estendida -r ):

Este script envolve o começo das linhas e das posições dos personagens. se você não quiser fazer isso, comente ou exclua a linha 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})(.*)/\*/ 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
    
por 04.11.2015 / 00:30