特定の文字列を含むファイル名のみを検索します。ファイルが圧縮されました(.gz
)。
インストールができていないためzgrep
インストールできません。したがって、そのオプションは使用できません-l
。
gzip
andgunzip
オプションを使用-c
して pipping しようとしましたが、grep -l
動作しません。また、ピッピングを試してみましたが、zcat
それも機能しません。どんな手がかりがありますか?
(注:オペレーティングシステムはSolaris 10です。)
答え1
zgrep操作を手動で実行できます。ファイル名だけが必要なので、パターンがgrep
あるかどうかをテストし、パターンが見つかったらファイル名を印刷するためのものです。
#!/bin/sh
pattern=$1; shift
PATH=`getconf PATH`:$PATH # needed on Solaris 10 and earlier
# to get a standard grep
export PATH
found=0
for x do
if case "$x" in
*.gz|*.[zZ]) <"$x" gzip -dc | grep -q -e "$pattern";;
*) <"$x" grep -q -e "$pattern";;
esac
then
found=1
printf '%s\n' "$x"
fi
done
if [ $found -eq 0 ]; then exit 1; fi
動作モードは次のとおりです。
that-script 'pattern' file1 file2.gz file3.Z file.*.gz ...
Solaris 10を実行するためのいくつかの特定のガイドライン(以前のバージョンおよびある程度Solaris 11にも適用可能)
- これらのシステムでは、
/bin/sh
標準のPOSIXの代わりにBourneシェルが使用されますsh
。#! /usr/xpg4/bin/sh -
標準を得るためにshe-bangを変更するsh
か、ここで述べたように古代のBourne構文に制限することができます(それでno$(...)
、nocase $x in (x)...
)(Solaris 11はこれを実装するためにPOSIX互換シェルを使用します(ksh93)。/bin/sh
)。 - これらのシステムでは、以前のように圧縮されたファイルのみが
zcat
処理されます。ファイルを呼び出す必要があります。.Z
compress
gzip
.gz
- デフォルトでは、標準ユーティリティを必ずしも得ることはできません。たとえば、デフォルトは古代
grep
オプション/usr/bin
であり、標準オプションをサポートしていません-q
。標準ユーティリティを取得するには、$PATH
標準ユーティリティを含むパス(出力など)を更新する必要がありますgetconf PATH
。
アーカイブメンバー名と行番号または内容を表示するには、grepから行データをインポートし、スクリプトからメンバー名を取得する必要があります。呼び出しから-q
オプションを削除grep
し、その内容を後処理します。
#!/bin/ksh
pattern=$1; shift
export PATH="$(getconf PATH):$PATH" # needed on Solaris 10 and earlier
# to get a standard grep
found=0
for x do
case "$x" in
*.gz|*.[zZ]) <"$x" gzip -dc | grep -n -e "$pattern";;
*) <"$x" grep -n -e "$pattern";;
esac | {
filename=$x awk '{print ENVIRON["filename"] ":" $0; found=1}
END {exit(!found)}' && found=1
}
done
if [ $found -eq 0 ]; then exit 1; fi
答え2
ファイルは実際にはtar.gzファイルなので、解凍する必要があります。 Tarは、複数のファイル(1つのみ)をまとめたアーカイブユーティリティで、元のデータをテープドライブにバックアップするために使用されました。
tarユーティリティは最初にコンテンツを圧縮しないため、通常はgzipまたは他のユーティリティを使用して圧縮のためにストリーミングされます。 tar.gz を解凍しても tar 実装階層はそのまま維持されるため、機能しません。
gun tarは「z」コマンドを使用して、単一のコマンドでtarおよびzip圧縮を実行します。
したがって、目的のタスクを実行するには、tarを使用してファイルターゲット「f」から「x」を抽出し、「z」を解凍してstdout「O」にストリーミングしてからgrepにパイプする必要があると思います。次のようにする必要があります。
tar -xzf mycompressedlogfile.tar.gz -O | grep -l "pattern"
あなたのtarバージョンには-zがないので、grepingする前にtarを通してgzipの出力をパイプしてみてください。
gzip -dc mycompressedlogfile.tar.gz | tar -xOf - | grep -l "pattern"
しかし、私はtarのSolaris 10バージョンがtarの内容をstdoutにストリーミングするための「O」オプションをサポートしていないと思います。 :(作業ディレクトリ内のすべてのファイルに対して上記の作業を実行する必要があるかもしれません(Oなしで "tar -xf -")、または何らかの方法で生成されたファイルを解釈できるかどうかを確認して申し訳ありませんが、Solarisではできない場合は、検索してみてください。マシンにgnu-tarをインストールしてください。
選択した回答でtarストリームからパターンを検索して(圧縮されていないので意味があると思います)そこから調べることができると思います。 :) 良いです。
答えを得たのは幸いです。
答え3
別の解決策は次のとおりです。
#!/bin/bash
# Grab the pattern, just like grep
re="$1"; shift
# Loop across the remaining arguments, or stdin if none
test 0 -eq $# && set -- -
for file
do
# Search through the file (compressed or otherwise)
zcat -f "$file" | grep -q "$re" && echo "$file"
done
ファイルにコピーしてそのファイルを実行可能にし、次のchmod a+x {filename}
ように使用する必要がありますzgrep
。
mkdir -p ~/bin
export PATH="$HOME/bin:$PATH" # Add the ~/bin directory to your PATH. Also add this line to your ~/.profile
cat > ~/bin/mygrep # Paste the file at this point, hit Ctrl/D on a blank line to end. Or otherwise edit ~/bin/mygrep
chmod a+x ~/bin/mygrep # Make it executable
mygrep 'hello.*world' a* # Search for the RE 'hello.*world' in all files beginning with 'a'
見つからzcat -f
ないかgrep -q
認識されない場合は、それぞれを次のように置き換えることができます
( zcat "$file" 2>/dev/null || cat "$file" ) # zcat -f "$file"
grep "$re" 2>/dev/null # grep -q "$re"
両方の置換を適用した後、結果の代替行は次のようになります。
( zcat "$file" 2>/dev/null || cat "$file" ) | grep "$re" 2>/dev/null && echo "$file"