xzgrep 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #!/bin/sh
  2. # xzgrep -- a wrapper around a grep program that decompresses files as needed
  3. # Adapted from a version sent by Charles Levert <charles@comm.polymtl.ca>
  4. # Copyright (C) 1998, 2001, 2002, 2006, 2007 Free Software Foundation
  5. # Copyright (C) 1993 Jean-loup Gailly
  6. # Modified for XZ Utils by Andrew Dudman and Lasse Collin.
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #SET_PATH - This line is a placeholder to ease patching this script.
  16. # Instead of unsetting XZ_OPT, just make sure that xz will use file format
  17. # autodetection. This way memory usage limit and thread limit can be
  18. # specified via XZ_OPT. With gzip, bzip2, and lzop it's OK to just unset the
  19. # environment variables.
  20. xz='xz --format=auto'
  21. unset GZIP BZIP BZIP2 LZOP
  22. case ${0##*/} in
  23. *egrep*) prog=xzegrep; grep=${GREP:-egrep};;
  24. *fgrep*) prog=xzfgrep; grep=${GREP:-fgrep};;
  25. *) prog=xzgrep; grep=${GREP:-grep};;
  26. esac
  27. version="$prog (XZ Utils) 5.2.2"
  28. usage="Usage: ${0##*/} [OPTION]... [-e] PATTERN [FILE]...
  29. Look for instances of PATTERN in the input FILEs, using their
  30. uncompressed contents if they are compressed.
  31. OPTIONs are the same as for '$grep'.
  32. Report bugs to <lasse.collin@tukaani.org>."
  33. # sed script to escape all ' for the shell, and then (to handle trailing
  34. # newlines correctly) turn trailing X on last line into '.
  35. escape='
  36. s/'\''/'\''\\'\'''\''/g
  37. $s/X$/'\''/
  38. '
  39. operands=
  40. have_pat=0
  41. files_with_matches=0
  42. files_without_matches=0
  43. no_filename=0
  44. with_filename=0
  45. while test $# -ne 0; do
  46. option=$1
  47. shift
  48. optarg=
  49. case $option in
  50. (-[0123456789abcdhHiIKLlnoqrRsTuUvVwxyzZ]?*)
  51. arg2=-\'$(expr "X${option}X" : 'X-.[0-9]*\(.*\)' | sed "$escape")
  52. eval "set -- $arg2 "'${1+"$@"}'
  53. option=$(expr "X$option" : 'X\(-.[0-9]*\)');;
  54. (--binary-*=* | --[lm]a*=* | --reg*=*)
  55. ;;
  56. (-[ABCDefm] | --binary-* | --file | --[lm]a* | --reg*)
  57. case ${1?"$option option requires an argument"} in
  58. (*\'*)
  59. optarg=" '"$(printf '%sX\n' "$1" | sed "$escape");;
  60. (*)
  61. optarg=" '$1'";;
  62. esac
  63. shift;;
  64. (--)
  65. break;;
  66. (-?*)
  67. ;;
  68. (*)
  69. case $option in
  70. (*\'*)
  71. operands="$operands '"$(printf '%sX\n' "$option" | sed "$escape");;
  72. (*)
  73. operands="$operands '$option'";;
  74. esac
  75. ${POSIXLY_CORRECT+break}
  76. continue;;
  77. esac
  78. case $option in
  79. (-[drRzZ] | --di* | --exc* | --inc* | --rec* | --nu*)
  80. printf >&2 '%s: %s: Option not supported\n' "$0" "$option"
  81. exit 2;;
  82. (-[ef]* | --file | --file=* | --reg*)
  83. have_pat=1;;
  84. (--h | --he | --hel | --help)
  85. echo "$usage" || exit 2
  86. exit;;
  87. (-H | --wi | --wit | --with | --with- | --with-f | --with-fi \
  88. | --with-fil | --with-file | --with-filen | --with-filena | --with-filenam \
  89. | --with-filename)
  90. with_filename=1
  91. continue;;
  92. (-l | --files-with-*)
  93. files_with_matches=1
  94. continue;;
  95. (-L | --files-witho*)
  96. files_without_matches=1
  97. continue;;
  98. (-h | --no-f*)
  99. no_filename=1;;
  100. (-V | --v | --ve | --ver | --vers | --versi | --versio | --version)
  101. echo "$version" || exit 2
  102. exit;;
  103. esac
  104. case $option in
  105. (*\'?*)
  106. option=\'$(expr "X${option}X" : 'X\(.*\)' | sed "$escape");;
  107. (*)
  108. option="'$option'";;
  109. esac
  110. grep="$grep $option$optarg"
  111. done
  112. if test $files_with_matches -eq 1 || test $files_without_matches -eq 1; then
  113. grep="$grep -q"
  114. fi
  115. eval "set -- $operands "'${1+"$@"}'
  116. if test $have_pat -eq 0; then
  117. case ${1?"Missing pattern; try \`${0##*/} --help' for help"} in
  118. (*\'*)
  119. grep="$grep -- '"$(printf '%sX\n' "$1" | sed "$escape");;
  120. (*)
  121. grep="$grep -- '$1'";;
  122. esac
  123. shift
  124. fi
  125. if test $# -eq 0; then
  126. set -- -
  127. fi
  128. exec 3>&1
  129. # res=1 means that no file matched yet
  130. res=1
  131. for i; do
  132. case $i in
  133. *[-.][zZ] | *_z | *[-.]gz | *.t[ag]z) uncompress="gzip -cdfq";;
  134. *[-.]bz2 | *[-.]tbz | *.tbz2) uncompress="bzip2 -cdfq";;
  135. *[-.]lzo | *[-.]tzo) uncompress="lzop -cdfq";;
  136. *) uncompress="$xz -cdfq";;
  137. esac
  138. # Fail if xz or grep (or sed) fails.
  139. xz_status=$(
  140. exec 5>&1
  141. ($uncompress -- "$i" 5>&-; echo $? >&5) 3>&- |
  142. if test $files_with_matches -eq 1; then
  143. eval "$grep" && { printf '%s\n' "$i" || exit 2; }
  144. elif test $files_without_matches -eq 1; then
  145. eval "$grep" || {
  146. r=$?
  147. if test $r -eq 1; then
  148. printf '%s\n' "$i" || r=2
  149. fi
  150. exit $r
  151. }
  152. elif test $with_filename -eq 0 &&
  153. { test $# -eq 1 || test $no_filename -eq 1; }; then
  154. eval "$grep"
  155. else
  156. case $i in
  157. (*'
  158. '* | *'&'* | *'\'* | *'|'*)
  159. i=$(printf '%s\n' "$i" |
  160. sed '
  161. $!N
  162. $s/[&\|]/\\&/g
  163. $s/\n/\\n/g
  164. ');;
  165. esac
  166. sed_script="s|^|$i:|"
  167. # Fail if grep or sed fails.
  168. r=$(
  169. exec 4>&1
  170. (eval "$grep" 4>&-; echo $? >&4) 3>&- | sed "$sed_script" >&3 4>&-
  171. ) || r=2
  172. exit $r
  173. fi >&3 5>&-
  174. )
  175. r=$?
  176. # fail occured previously, nothing worse can happen
  177. test $res -gt 1 && continue
  178. test "$xz_status" -eq 0 || test "$xz_status" -eq 2 \
  179. || test "$(kill -l "$xz_status" 2> /dev/null)" = "PIPE" || r=2
  180. # still no match
  181. test $r -eq 1 && continue
  182. # 0 == match, >=2 == fail
  183. res=$r
  184. done
  185. exit $res