3
/path/to/fname#line1242

Is there a way to refer to a specific line number in a file as part of the pathname, or some way to package a link to a line number, which looks/behaves like a pathname? For example, giving the string above to another user of the same filesystem so that they can easily open my file "fname" and instantly be on line 1242 therein.

I'm thinking of behavior similar to HTML anchors, which can be included inline with the URI to a page, and then behave just like links. Namely, they can be given to other users of the same filesystem and will indicate a given line in the file to those users, opening the file by default to that line. I realize that in UNIX the only things that can truly be part of a pathname may be directories, files and pseudo-files. But then there are globs, string expansion, etc., which are not strictly part of a pathname but can be interposed in one "comfortably", while the filename is passed around and referenced, without entailing any additional commands. Is there an inline way to simulate anchor/link behavior like this for a UNIX file?

I could include command substitution in my "pathname" with sed "1242p" and some kind of self-reference, but then I'm no longer dealing with a pathname, just a command operating on a file. Come to think of it, then I would not be linking, just extracting a line. I can't think of a way to link to a specific line at all (without ignoring the rest of the file).

GNU bash, version 3.2.51

  • You could put a the sed call in a variable and then call whenever you need it. Similar to what you said. But you want this as a file? A file that points at a line in a file? – phk Dec 28 '16 at 20:40
  • You can sort of simulate it by using <(tail filename -n +linenumber) instead of filename. But if you really mean a pathname then no. Files may have pathnames. Parts of files cannot have pathnames. There are operating systems and filesystems such as Windows and NTFS where files may consist of more than one data stream and those streams have pathnames, but you may have noticed that although this is possible very few Windows programs use it. – AlexP Dec 28 '16 at 20:42
  • filename:linenumber is a common convention, but something else then needs to parse out the file and line bits, hopefully while remembering that filenames can include colons...why do you need the linenumber detail passed around? – thrig Dec 28 '16 at 21:13
  • 3
    Do you have a specific example in mind? Or, could you create an example to share here? I'm not quite sure what you're trying to do. – dafydd Dec 28 '16 at 21:13
  • 2
    Do you mean $PATH when you refer to a "path"? If not, please choose a different word or make it clear in your question that your use of the word "path" is nothing to do with $PATH. A worked example would be really helpful to understand what you're trying to achieve. But please put these amendments in your question, and not here in the comments. – roaima Dec 28 '16 at 22:00
2

You could create a file called +view +1242 fname. Then calling vi or view on that file:

view '+view +1242 fname'

would open fname in view and put the cursor at the beginning of the 1242nd line (here assuming the vim implementation of vi/view).

Or do:

ln -s / '+view +1242 '

So you do:

view '+view +1242 /etc/passwd'

to view /etc/passwd at line 1242.

Or:

touch '+exe "view +1242 \57etc\57passwd"'

And view that with:

view '+exe "view +1242 \57etc\57passwd"'

You could also make the top line of the target file:

#! /usr/bin/less +1242

And make it executable (chmod +x fname) and execute it for it to be open by less at the 1242nd line.

  • 1
    This may be the closest thing to what I imagined when I asked - and it is quite cool. But if I try to put the full pathname in there I get "touch: cannot touch `+view +1242 /path/to/fname': No such file or directory" – WAF Dec 30 '16 at 16:39
  • @WAF, see edit. – Stéphane Chazelas Dec 30 '16 at 18:31
2

Indeed there's no way to link to a part of a file. Links are file-level tools, they only allow accessing a file under a particular name, they don't do anything about file contents.

If you only want to read from the file then you can use a named pipe:

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

and then anybody who reads fname_line1242 will get line 1242 of /path/to/fname… if they're lucky. Named pipes don't have any form of synchronization, so this will only work reliably if there's only one reader at a time.

To make this work with multiple readers, you can use a socket and run socat to execute a command to produce content each time the socket is read.

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

If you want writes to the file to replace the line in /path/to/fname, it's possible, but considerably more difficult. You can use FUSE to create custom filesystems where operations such as opening a file, reading, writing, etc. execute code that you write. This requires significant effort unless somebody has already written a filesystem that does what you want.

1

Well, you could build an URI to a local file, like:

file:///home/user/filename

And then you could insert a #Part3 guide:

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

but you need the file to be in html if a browser is to be used to read the file.


The real question then becomes: What program (tool) is to be reading (showing) the file?

The answer is above if you expect a browser to read it.

If you use less (the usual reader of man pages), you can direct less to go to an specific line:

less +20 filename

To read a text file with line number 20 at the start of the console.

If you could change the filename to include the line number required.
Something like: filename-line-233, this will work:

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

There may be other tools that could be adapted to this idea.

0

With markdown you seem to be able to refer to lines in a file:

github link

  • I'm looking for something built in (or close to it) in UNIX, rather than something that requires interpretation like a markup or markdown language. But I don't actually see what you are referring to on that page (unless you are referring to your link itself, which it appears goes to an HTML anchor). – WAF Dec 29 '16 at 13:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.