Blog 1

Random Talk on Random Thoughts

Find Files for Vim to Edit in Bash

| Comments |


Since copying and pasting the output of a command can be a tedious job. For example, if you want to create your blog using a framework, you may first logon to your GitHub account and create an empty repository there, then git clone Octopress/Jekyll-Bootstrap from GitHub, reset the origin URL, and input the new URL based on the old one.

After having created a repository online, you will see the URL of the repository using the SSH protocol. If one doesn’t want to repeat the start of the URL, one may use the bash commands introduced in the previous post to extract its useful parts for the sed substitution.

$ git remote -v
octopress (fetch)
octopress (push)
origin (fetch)
origin (push)
$ name=userName; repo=repoName
$ git remote -v | sed -n '3{p;q}' | awk '{print $2}' | sed -r \
$ unset name repo


I tried extracting a list of Markdown files containing a particular word and passing them to Vim as arguments using find, grep and xargs. Unluckily, I got an error.

$ find source/_posts/ -name "*.markdown" -exec grep -q ^tag {} \; \
> -print | xargs vi
Vim: Warning: Input is not from a terminal
3 files to edit

Note: Without the -print flag, the above command won’t work.


As a result, I searched “vim warning input is not from a terminal xargs” on Google, and found this question very useful. I should have wrapped the find command like $(find ...).

$ vi $(find source/_posts/ -name "*.markdown" -exec \
> grep -q ^tag {} \; -print | xargs)
3 files to edit

Facts learnt


  • 3{p;q}: quit after printing the third line for the sake of efficiency
  • -r: use extended regular expression to save the trouble of escaping () for submatches.
  • -n: suppress standard output.
  • Enclose the expression
    • with single quotes to disable interpretation of bash variables
    • with double quotes to enable interpretation of bash variables.
  • One can replace the delimiter / in the expression s/{pat}/{repl}/ by any one character from _;#| .
  • Specify a custom delimiter like \%.%s%foo%bar%. (The variable/range . is needed.)


  • Set variables using var1=value1;var2=value2;...
  • Unset variable usign unset var1 var2 ...