両方のファイルから複数の文字列を検索したいと思います。両方のファイルで文字列が見つかった場合は、その文字列で何かをします。文字列が1つのファイルでのみ見つかった場合は、別の操作を実行してください。
私のコマンドは次のとおりです。
####This is for the affirmative sentence in both files
if grep -qw "$users" "$file1" && grep -qw "$users" "$file2"; then
####This is for the affirmative sentence in only one file, and negative for the other one
if grep -qw "$users" "$file1" ! grep -qw "$users" "$file2"; then
ステートメントを拒否して確認する正しい方法はありますか? pd 私はKSHシェルを使っています。
よろしくお願いします。
答え1
別のオプション:
grep -qw -- "$users" "$file1"; in_file1=$?
grep -qw -- "$users" "$file2"; in_file2=$?
case "${in_file1},${in_file2}" in
0,0) echo found in both files ;;
0,*) echo only in file1 ;;
*,0) echo only in file2 ;;
*) echo in neither file ;;
esac
答え2
この試み:
if grep -wq -- "$user" "$file1" && grep -wq -- "$user" "$file2" ; then
echo "string avail in both files"
elif grep -wq -- "$user" "$file1" "$file2"; then
echo "string avail in only one file"
fi
grep
複数のファイルからパターンを検索できるため、OR / NOT演算子を使用する必要はありません。
答え3
n=0
#Or if you have more files to check, you can put your while here.
grep -qw -- "$users" "$file1" && ((n++))
grep -qw -- "$users" "$file2" && ((n++))
case $n in
1)
echo "Only one file with the string"
;;
2)
echo "The two files are with the string"
;;
0)
echo "No one file with the string"
;;
*)
echo "Strange..."
;;
esac
注:((n++))
ksh拡張子です(zsh
およびサポートされていますbash
)。 POSIXsh
構文では、に変更する必要がありますn=$((n + 1))
。
答え4
ファイル名に改行文字が含まれていない場合は、grep
grepに一致するファイル名を印刷して結果を計算することで、複数の呼び出しを回避できます。
local IFS=$'\n' # inside a function. Otherwise use some other way to save/restore IFS
matches=( $(grep -lw "$users" "$file1" "$file2") )
ゲーム数はです"${#matches[@]}"
。
これを使用する方法があるかもしれませんが、grep --null -lw
出力を解析する方法がわかりません。。 Bashでは、区切り文字を代わりにvar=( array elements )
使用する方法はありません。たぶんbashの組み込み機能はこれを行うことができますか?しかし、おそらくそうではありません。で区切り文字を指定したためです。\0
\n
mapfile
-d string
可能ですが、2つの外部プロセスがあるため、2つのファイルを別々に実行することをお勧めしますcount=$(grep -l | wc -l)
。 (開始オーバーヘッドと開始オーバーヘッドの違いは、grep
別のプロセスを開始するfork + exec +ダイナミックリンカーと比較して小さいです。)grep
wc
そしてwc -l
私はあなたからそれに気づかなかった。どのファイルの一致。
結果を配列としてキャプチャすると、すでに必要なものにすることも、正確に1つの一致がある場合は最初の入力であることを確認することもできます。
local IFS=$'\n' # inside a function. Otherwise use some other way to save/restore IFS
matches=( $(grep -lw "$users" "$file1" "$file2") )
# print the matching filenames
[[ -n $matches ]] && printf 'match in %s\n' "${matches[@]}"
# figure out which input position the name came from, if there's exactly 1.
if [[ "${#matches[@]" -eq 1 ]]; then
if [[ $matches == "$file1" ]];then
echo "match in file1"
else
echo "match in file2"
fi
fi
$matches
${matches[0]}
最初の配列要素の略語です。