Bash/Mgrep

From Attie's Wiki
(Difference between revisions)
Jump to: navigation, search
m
m
 
(9 intermediate revisions by one user not shown)
Line 1: Line 1:
 
This is a useful tool that extends grep.
 
This is a useful tool that extends grep.
 
* Expression input is at the front, allowing quick & easy editing
 
* Expression input is at the front, allowing quick & easy editing
* Recursively locates all files named (e.g: <code>*.c</code>)
+
* Search directory defaults to <code>.</code>, but can be easily modified
* Files checked defaults to '<code>*.c</code>' and '<code>*.h</code>', but can be easily changed
+
* Files checked defaults to '<code>*.c</code>', '<code>*.cpp</code>' and '<code>*.h</code>', but can be easily changed
* Multiple filenames / masks may be specified
+
* Recursively locates all files matching given names (e.g: <code>*.c</code>)
 +
* Multiple filenames / masks / patterns may be specified
 
* Uses <code>grep</code>'s extended regex mode
 
* Uses <code>grep</code>'s extended regex mode
 
* Output shows file and line number, and is highlighted
 
* Output shows file and line number, and is highlighted
Line 9: Line 10:
 
* If the output ''doesnt'' flow over the screen, <code>less</code> quits immediately
 
* If the output ''doesnt'' flow over the screen, <code>less</code> quits immediately
 
* Automatically detects if the output is to a terminal or pipe, utilizing <code>less</code> and highlighting for the former
 
* Automatically detects if the output is to a terminal or pipe, utilizing <code>less</code> and highlighting for the former
 +
* By default uses case ''insensitive'' search, just setting GREP_OPTIONS (even to empty) will disable this
  
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/bash
 
#!/bin/bash
  
if [ $# -lt 2 ]; then
+
if [ $# -lt 1 ]; then
 
   echo "usage:"
 
   echo "usage:"
   echo "  $0 <expression> <directory> [filename..]"
+
   echo "  $0 <expression> [directory] [filename..]"
 
   exit 1
 
   exit 1
 
fi
 
fi
  
 
EXPRESSION="$1";    shift
 
EXPRESSION="$1";    shift
DIRECTORY="$1";    shift
 
  
 
if [ $# -lt 1 ]; then
 
if [ $# -lt 1 ]; then
   FILES="-name '*.c' -or -name '*.h'"
+
  DIRECTORY="."
 +
else
 +
  DIRECTORY="$1";    shift
 +
fi
 +
 
 +
if [ $# -lt 1 ]; then
 +
   FILES="-name '*.c' -or -name '*.cpp' -or -name '*.h'"
 
else
 
else
 
   FILES="-name '$1'"; shift
 
   FILES="-name '$1'"; shift
Line 30: Line 37:
 
   done
 
   done
 
fi
 
fi
 +
CMD="find \"${DIRECTORY}\" ${FILES}"
  
 
if [ -t 1 ]; then
 
if [ -t 1 ]; then
 
   PIPE=/tmp/$$.mgrep
 
   PIPE=/tmp/$$.mgrep
   trap "rm -f ${PIPE}" EXIT
+
   #trap "exec 1>&-; sleep 0.1; rm -f ${PIPE}" EXIT
 
   mknod ${PIPE} p
 
   mknod ${PIPE} p
 
   less -FKnRX < ${PIPE} &
 
   less -FKnRX < ${PIPE} &
   exec 1>&-
+
   exec 3>&1
 
   exec 1>${PIPE}
 
   exec 1>${PIPE}
 
   GREP_OPTIONS="--color=always ${GREP_OPTIONS}"
 
   GREP_OPTIONS="--color=always ${GREP_OPTIONS}"
 +
else
 +
  PIPE=""
 
fi
 
fi
  
CMD="find \"${DIRECTORY}\" ${FILES}"
 
 
eval ${CMD} | \
 
eval ${CMD} | \
 
while read -r f; do
 
while read -r f; do
   grep -niH -E ${GREP_OPTIONS} "${EXPRESSION}" "${f}"
+
   grep -niH -E ${GREP_OPTIONS} -- "${EXPRESSION}" "${f}"
 
done
 
done
 +
 +
if [ "${PIPE}" != "" ]; then
 +
  exec 1>&3
 +
  exec 3>&-
 +
  wait
 +
  rm -f ${PIPE}
 +
fi
 
</source>
 
</source>

Latest revision as of 10:34, 13 March 2013

This is a useful tool that extends grep.

  • Expression input is at the front, allowing quick & easy editing
  • Search directory defaults to ., but can be easily modified
  • Files checked defaults to '*.c', '*.cpp' and '*.h', but can be easily changed
  • Recursively locates all files matching given names (e.g: *.c)
  • Multiple filenames / masks / patterns may be specified
  • Uses grep's extended regex mode
  • Output shows file and line number, and is highlighted
  • If the output flows over the screen, less allows you to review the results
  • If the output doesnt flow over the screen, less quits immediately
  • Automatically detects if the output is to a terminal or pipe, utilizing less and highlighting for the former
  • By default uses case insensitive search, just setting GREP_OPTIONS (even to empty) will disable this
#!/bin/bash
 
if [ $# -lt 1 ]; then
  echo "usage:"
  echo "  $0 <expression> [directory] [filename..]"
  exit 1
fi
 
EXPRESSION="$1";    shift
 
if [ $# -lt 1 ]; then
  DIRECTORY="."
else
  DIRECTORY="$1";     shift
fi
 
if [ $# -lt 1 ]; then
  FILES="-name '*.c' -or -name '*.cpp' -or -name '*.h'"
else
  FILES="-name '$1'"; shift
  while [ $# -ne 0 ]; do
    FILES="${FILES} -or -name '$1'"; shift
  done
fi
CMD="find \"${DIRECTORY}\" ${FILES}"
 
if [ -t 1 ]; then
  PIPE=/tmp/$$.mgrep
  #trap "exec 1>&-; sleep 0.1; rm -f ${PIPE}" EXIT
  mknod ${PIPE} p
  less -FKnRX < ${PIPE} &
  exec 3>&1
  exec 1>${PIPE}
  GREP_OPTIONS="--color=always ${GREP_OPTIONS}"
else
  PIPE=""
fi
 
eval ${CMD} | \
while read -r f; do
  grep -niH -E ${GREP_OPTIONS} -- "${EXPRESSION}" "${f}"
done
 
if [ "${PIPE}" != "" ]; then
  exec 1>&3
  exec 3>&-
  wait
  rm -f ${PIPE}
fi
Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox