0

I tried opening files with vim using vim $(cat filelist) as suggested from this earlier question.

Suppose I have the following file:

~/Workspace/bar/foo.cpp

Executing vim $(cat filelist) from ~/Workspace correctly opens foo.cpp when filelist contains bar/foo.cpp. However, the command does not open the file when filelist contains ~/Workspace/bar/foo.cpp. I want to know why using the absolute path causes the command to fail.

Abhilash
  • 339

1 Answers1

1

This is due to the order in which the different types of expansions are performed in a shell. The bash manpage says:

Expansion is performed on the command line after it has been split into words. There are seven kinds of expansion performed: brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, word splitting, and pathname expansion.

Replacing the ~ is tilde expansion, while your $(...) is command substitution. Now you see that after the command substitution is performed, there is no more tilde substitution. With real absolute paths (starting at file system root /) it would work.

But you can perform the expansion by yourself with sed:

vim $(sed "s_~_${HOME}_g" filelist)
Philippos
  • 13,453
  • Thanks for the quote from the man page, it really helps me understand the underlying mechanics of the commandline. – Abhilash Jun 04 '21 at 16:55
  • @Abhilash: This fails when files or path components have ~ anywhere in their name, which is permitted. Add ^ in front of ~ in your regex matching of pattern space and drop the global flag g at the end of the substitution, unless filelist contains more than one file record per line, although in this case a new issue would be how to distinguish two consecutive records and sed might not be the best tool anymore. Also require the presence of / or be ready to deal with legit instances of ~USER/ in fqp of files. In the end I would do vim $(sed "s_^~/_${HOME}/_" filelist). – Cbhihe Jun 05 '21 at 06:24