Bash: caminho ou link para uma linha em um arquivo?

3
/path/to/fname#line1242

Existe uma maneira de se referir a um número de linha específico em um arquivo como parte do nome do caminho, ou alguma forma de empacotar um link para um número de linha, que parece / se comporta como um nome de caminho? Por exemplo, dar a string acima para outro usuário do mesmo sistema de arquivos para que eles possam facilmente abrir meu arquivo "fname" e instantaneamente estar na linha 1242 nele.

Estou pensando em comportamentos semelhantes a âncoras HTML, que podem ser incluídos na linha com o URI em uma página e, em seguida, comportar-se como links. Ou seja, eles podem ser fornecidos a outros usuários do mesmo sistema de arquivos e indicarão uma determinada linha no arquivo para esses usuários, abrindo o arquivo por padrão para essa linha. Eu percebo que no UNIX as únicas coisas que podem verdadeiramente fazer parte de um nome de caminho podem ser diretórios, arquivos e pseudo-arquivos. Mas então há globs, expansão de string, etc., que não são estritamente parte de um nome de caminho, mas podem ser interpostos em um "confortavelmente", enquanto o nome do arquivo é passado e referenciado, sem envolver quaisquer comandos adicionais. Existe uma maneira inline para simular o comportamento de âncora / link como este para um arquivo UNIX?

Eu poderia incluir a substituição de comandos no meu "nome do caminho" com sed "1242p" e algum tipo de auto-referência, mas não estou mais lidando com um nome de caminho, apenas com um comando operando em um arquivo. Venha para pensar sobre isso, então eu não estaria ligando, apenas extraindo uma linha. Não consigo pensar em uma maneira de vincular a uma linha específica (sem ignorar o restante do arquivo).

GNU bash, versão 3.2.51

    
por WAF 28.12.2016 / 21:32

4 respostas

2

Você pode criar um arquivo chamado +view +1242 fname . Em seguida, chamando vi ou view nesse arquivo:

view '+view +1242 fname'

abrirá fname em view e colocará o cursor no início da linha 1242 nd (assumindo aqui a implementação vim de vi / view ).

Ou faça:

ln -s / '+view +1242 '

Então você faz:

view '+view +1242 /etc/passwd'

para visualizar /etc/passwd na linha 1242.

Ou:

touch '+exe "view +1242 etcpasswd"'

E view com:

view '+exe "view +1242 etcpasswd"'

Você também pode criar a linha superior do arquivo de destino:

#! /usr/bin/less +1242

E torne-o executável ( chmod +x fname ) e execute-o para que ele seja aberto por less na linha 1242 nd .

    
por 30.12.2016 / 17:31
2

Bem, você pode criar um URI para um arquivo local, como:

file:///home/user/filename

E então você pode inserir um guia # Part3:

file:///home/user/filename#Part3

mas você precisa que o arquivo esteja em html se um navegador for usado para ler o arquivo.

A questão real então se torna: Qual programa (ferramenta) deve estar lendo (mostrando) o arquivo?

A resposta está acima, se você espera que um navegador a leia.

Se você usa less (o leitor comum de páginas man), você pode direcionar menos para ir para uma linha específica:

less +20 filename

Para ler um arquivo de texto com o número de linha 20 no início do console.

Se você pudesse alterar o nome do arquivo para incluir o número de linha necessário.
Algo como: filename-line-233 , isso funcionará:

$ filename=A-text-file-line-233
$ less +"${filename##*-}" "$filename"

Pode haver outras ferramentas que possam ser adaptadas a essa ideia.

    
por 28.12.2016 / 22:40
2

Na verdade, não há como vincular uma parte de um arquivo. Links são ferramentas de nível de arquivo, eles permitem apenas acessar um arquivo com um nome específico, eles não fazem nada sobre o conteúdo do arquivo.

Se você quiser apenas ler o arquivo, use um canal nomeado :

mkfifo fname_line1242
while true; do sed -n '1242 { p; q; }' /path/to/fname >fname_line1242; done

e então qualquer um que ler fname_line1242 receberá a linha 1242 de /path/to/fname ... se tiver sorte. Os pipes nomeados não têm qualquer forma de sincronização, portanto, isso só funcionará de maneira confiável se houver apenas um leitor por vez.

Para que isso funcione com vários leitores, você pode usar um soquete e executar socat para executar um comando para produzir conteúdo toda vez que o socket for lido.

socat -U UNIX-LISTEN:fname_line1242,unlink-early,fork EXEC:'sed -n -e 1242{ -e p -e q -e } /path/to/fname'

Se você quiser gravar no arquivo para substituir a linha em /path/to/fname , é possível, mas consideravelmente mais difícil. Você pode usar o FUSE para criar sistemas de arquivos personalizados onde operações como abrir um arquivo, ler, escrever, etc. executam códigos que você escreve. Isso requer um esforço significativo, a menos que alguém já tenha escrito um sistema de arquivos que faça o que você quer.

    
por 29.12.2016 / 02:23
0

Com a marcação, parece que você pode se referir a linhas em um arquivo:

link do github

    
por 29.12.2016 / 07:31