#!/bin/dash
PrintInTitle () {
printf "\033]0;%s\007" "$1"
}
PrintJustInTitle () {
PrintInTitle "$1">"$print_to_screen"
}
CleanUp () {
trap - INT
trap - TSTP
if [ -n "$TEP" ] && [ -n "$TEF" ]; then
rm -R -f "$output_dir/"*
fi
unset IFS
PrintJustInTitle ""
if [ "$1" = "1" ]; then
printf "Aborted\n">"$print_to_screen"
kill -s PIPE -- -$$ 2>/dev/null
fi
}
StoreArchiveFilePath () {
eval k=$(($k + 1))
eval archive_files_$k="$archive_file"
}
PrintMatch () {
printf '\n%s\n\n' "$search_path$current_archive_file/$inside_current_archive_file"|grep --color -F "$search_path$current_archive_file/$inside_current_archive_file"
for i in $(seq 1 $search_strings_0); do
eval current_search_string="$search_strings_$i"
printf '\n%s\n\n' "$current_search_string:"|grep --color -F "$current_search_string:"
cat "$inside_current_archive_file"|grep -i -n -F "$current_search_string" 2>/dev/null
done
}
GetCurrentContent () {
cd "$TEP" && {
eval current_archive_file="$$2"
case "$current_archive_file" in
'.zip' )
unzip "$full_search_path/""$current_archive_file" -d "$TEF" >/dev/null 2>/dev/null
;;
'.bz2' )
bzip2 "$full_search_path/""$current_archive_file" -d "$TEF" >/dev/null 2>/dev/null
;;
'.xz' )
xz "$full_search_path/""$current_archive_file" -d "$TEF" >/dev/null 2>/dev/null
;;
'.tar.'* | '.tgz' | '.tar' )
tar -xvf "$full_search_path/""$current_archive_file" -C "$TEF" >/dev/null 2>/dev/null
;;
*'.gz' )
cp "$full_search_path/""$current_archive_file" "./$TEF"; gzip -d "./$TEF/""$current_archive_file" >/dev/null 2>/dev/null
;;
esac
cd "$output_dir"
for inside_current_archive_file in $(for t in $(seq 1 $inside_archive_file_path_filters_0); do eval current_inside_archive_file_path_filter=\"\$inside_archive_file_path_filters_$t\"; eval find . -type f -path "$current_inside_archive_file_path_filter"|sort --numeric-sort; done;); do
gcc_found="true"
for i in $(seq 1 $search_strings_0); do
eval current_search_string=\"\$search_strings_$i\"
gcc_stored_content="$(cat "$inside_current_archive_file"|grep -i -n -F "$current_search_string" 2>/dev/null;)";
if [ -z "$gcc_stored_content" ]; then
gcc_found="false"
break
fi
done
if [ "$gcc_found" = "true" ]; then
if [ "$1" = "StoreArchiveFilePath" ]; then
StoreArchiveFilePath
break
elif [ "$1" = "PrintMatch" ]; then
PrintMatch
fi
fi
done
if [ -n "$TEP" ] && [ -n "$TEF" ]; then rm -R -f "$output_dir/"*; fi
cd "$full_search_path"
}
}
set +f #Enable globbing (POSIX compliant)
setopt no_nomatch 2>/dev/null #Enable globbing (zsh)
IFS='
'
print_to_screen='/dev/tty'
initial_dir="$PWD"
case "$(uname -s)" in
"Linux" )
TEP='/dev/shm' #TEMPORARY_EXTRACT_PATH
;;
"Darwin" | "BSD" | * )
TEP="$HOME" #TEMPORARY_EXTRACT_PATH
;;
esac
TEF='TEMP_EXTRACT_FOLDER' #TEMP_EXTRACT_FOLDER
output_dir=""
error="false"
{
cd "$TEP" && {
if [ ! -e "$TEF" ]; then
printf '%s\n' "The specified temporary directory: "$TEF" - does not exist in the specified location: "$TEP" - do you want to create it? [ Yes / No ] (default=Enter=No): ">"$print_to_screen"
read answer
if [ "$answer" = "Yes" ] || [ "$answer" = "yes" ] || [ "$answer" = "Y" ] || [ "$answer" = "y" ]; then
mkdir "$TEF" || error="true"
fi
fi
cd "$TEF" && output_dir="$PWD" || error="true"
} || error="true"
} 2>/dev/null
if [ "$error" = "true" ]; then
printf '%s\n' "Error: Could not access temporary folder "$TEF" in the extract location: "$TEP"!">&2
read temp
exit 1
fi
trap 'CleanUp 1' INT
trap 'CleanUp 1' TSTP
cd "$HOME"
printf '%s\n' "Search Path (blank=default=current folder=$PWD): "
read search_path
if [ -z "$search_path" ]; then
search_path="."
fi
printf '\n%s\n' "Inside archive file path filters: (what file path to lookup inside the archive) (concatenated internaly with logical OR) (default=Enter=''): ">"$print_to_screen"
i=0
while [ "1" = "1" ]; do
printf '%s' ">> inside archive path filter: >> "
IFS= read -r current_inside_archive_file_path_filter
unset IFS
if [ -z "$current_inside_archive_file_path_filter" ]; then
break
fi
i=$(($i + 1))
eval inside_archive_file_path_filters_$i="$current_inside_archive_file_path_filter"
done
inside_archive_file_path_filters_0=$i
unset IFS #Reset IFS
if [ "$inside_archive_file_path_filters_0" = "0" ]; then
inside_archive_file_path_filters_1="'"''"'"
inside_archive_file_path_filters_0="1"
fi
printf '\n%s\n' "Search strings (concatenated internaly with logical AND):">"$print_to_screen";
i=0
while [ "1" = "1" ]; do
printf '%s' ">> add search string: >> "
IFS= read -r current_search_string
unset IFS
if [ -z "$current_search_string" ]; then break; fi;
i=$(($i + 1))
eval search_strings_$i="$current_search_string"
done
search_strings_0=$i
if [ "$search_strings_0" = "0" ]; then
search_strings_1=""
search_strings_0=1
fi
i=0
PrintJustInTitle "Loading list of archive files to analyze..."
IFS='
'
cd "$search_path" && {
full_search_path="$PWD"
{ find . ( -type f -path '.zip' -o -path '.bz2' -o -path '.xz' -o -path '.tar.' -o -path '.tgz' -o -path '.tar' -o -path '.gz' ) -exec printf "%s\n" "{}" ;|sort --numeric-sort;
printf '%s\n' "..."; index=defined; while [ -n "$index" ]; do read index; printf '%s\n' $index; done; }|{
j=0; k=0
while read -r line; do
j=$(($j + 1))
if [ "$line" = "..." ]; then
break
else
PrintJustInTitle "Analyzing archive file $j..."
archive_file="$line"
fi
GetCurrentContent StoreArchiveFilePath archive_file
done
archive_files_0="$k"
PrintJustInTitle ""
if [ ! "$k" = "0" ]; then
index="defined"
count="$archive_files_0"
while [ -n "$index" ]; do
for i in $(seq 1 $count); do
eval current_archive_file=\"\$archive_files_$i\"
printf '\033[0;31m%s\033[0m\n' "$i = ""$current_archive_file"
done
printf '\n%s\n' "Print results (one at a time - blank = exit)?: [ 1 - $count ]: "
read index
if [ -z "$index" ]; then
break
fi
printf '%s\n' '---------------------------------------------------------------'
GetCurrentContent PrintMatch archive_files_$index
printf '%s\n\n' '---------------------------------------------------------------'
done
fi
}
}
PrintJustInTitle ""
CleanUp
~/.avfs
), and access to each archive is automatic (~/.avfs/path/to/archive.zip\#
is an ordinary directory on the AVFS filesystem, not a mount point). Sure, each archive you access means a little performance hit, but that's intrinsic to the problem. – Gilles 'SO- stop being evil' May 28 '11 at 14:31find: missing argument to
-exec'and lots of this from zsh
zsh: Input/output error: Data-Maker-0.27` – xenoterracide May 28 '11 at 15:36{\}
) in the inner find call. Both shell snippets should work now. – Gilles 'SO- stop being evil' May 29 '11 at 18:02grep: /home/xenoterracide/.avfs/srv/http/cpan/authors/id/J/JI/JINGRAM/Data-Maker-0.27.tar.gz#/Data-Maker-0.27/lib/Data/PaxHeader/Maker.pm: Input/output error
– xenoterracide May 29 '11 at 23:48tar tzf Data-Maker-0.27.tar.gz
doesn't find thePaxHeader
directory and prints many errors such astar: Ignoring unknown extended header keyword `SCHILY.dev'
). AVFS can be told to call external programs, so you could install star and have AVFS call it: define anstar
vfs suffix (see the AVFS README) and usefoo.tgz#star/dir
instead offoo.tgz#/dir
. – Gilles 'SO- stop being evil' May 30 '11 at 00:17