だからファイルの文字列/または単語を一致させたいのですがいいえ外部ツール(grep
などsed
)を使用してください。純粋なbashだけを使用してください。
本質的に私は次のようなものが欲しい。
grep "string" file
または
grep -w "string" file
純粋なbashで。
PS:私はファイル内の正確な文字列を一致させることに興味があるので(改行の有無にかかわらず)完全な正規表現のサポートは必要ありません(他の外部ツールがそれをサポートできます)。
答え1
できます。しかし、これは非常に非常に悪い考えです。grep
特定のシェル(Bash)の機能に依存するため、次のものよりはるかに遅くなります(数十倍遅い)。
これにより、次のように、最初の引数として指定された正規表現パターンに一致する行が印刷されますgrep pattern
。
#!/bin/bash -
regexp="$1"
ret=1
while IFS= read -r line || [ -n "$line" ]; do
if [[ $line =~ $regexp ]]; then
printf '%s\n' "$line"
ret=0
fi
done
exit "$ret"
別の名前で保存しfoo.bash
て、次のように実行してください。
foo.bash pattern < inputFile
または、標準sh
構文を使用して正規表現の代わりに固定文字列を検索します。
#!/bin/sh -
string="$1"
ret=1
while IFS= read -r line || [ -n "$line" ]; do
case $line in
(*"$string"*)
printf '%s\n' "$string"
ret=0
esac
done
exit "$ret"
(のようなものを得るためprintf
にに置き換えてください。)exit 0
grep -q
どれくらい遅いかを知らせるために、10001行だけのファイルを作成しました。最初の5000行はfoo
、次に1行bar
、もう1つの5000行は次のとおりですfoo
。
perl -e 'print "foo\n" x 5000; print "bar\n"; print "foo\n" x 5000;' > file
grep
さて、上記のスクリプトのタイミングを比較してみましょう。
$ time grep bar < file
bar
real 0m0.002s
user 0m0.002s
sys 0m0.000s
$ time ./foo.bash bar < file
bar
real 0m0.116s
user 0m0.101s
sys 0m0.016s
ご覧のとおり、ファイルサイズが小さくても差が目立つ。より実用的なスクリプトを使用しようとすると、スクリプトにほとんど耐えられない時間がかかります。
$ perl -e 'print "foo\n" x 500000; print "bar\n"; print "foo\n" x 500000;' > file
$ time grep bar < file
bar
real 0m0.004s
user 0m0.000s
sys 0m0.004s
$ time ./foo.bash bar < file
bar
real 0m11.306s
user 0m10.117s
sys 0m1.188s
しかし、これは部分的にBashが遅いからです。標準のshバージョンは、Dashを使用してより速く実行されます。
$ time dash foo2.sh bar < file
bar
real 0m3.467s
user 0m2.113s
sys 0m1.353s
しかし、まだ格差がある。3倍のスケール。スクリプトはほとんど瞬間的ではなく数秒かかりますgrep
。このファイルはまだ100万行にすぎず、サイズは約4MBです。問題を見ることを願っています。