Eu quero pesquisar várias seqüências de caracteres em dois arquivos. Se uma string for encontrada nos dois arquivos, faça alguma coisa. Se uma string for encontrada em apenas um arquivo, faça outra coisa.
Meus comandos são os seguintes:
####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
é correto o modo de negar e afirmar as afirmações? Estou usando o shell KSH.
Agradeço antecipadamente.
text-processing
awk
grep
ksh
Mareyes
fonte
fonte
Outra opção:
fonte
Nota:
((n++))
é uma extensão ksh (também suportada porzsh
ebash
). Nash
sintaxe POSIX , você precisarian=$((n + 1))
.fonte
n=$((n++))
NUNCA alterará o valor de n porquen++
é pós- incremento: retorna o valor atual de n e depois incrementa n; então você define a variável para o valor retornado, que era o n original.local IFS=$'\n'; matches=( $(grep -lw "$users" "$file1" "$file2") )
e usecase "${#matches[@]" in
. @ Glenn: essa idéia também se aplica à sua resposta, para evitar múltiplas invocações degrep
. Encaná-logrep -l | wc -l
também funcionaria.Se os seus nomes de arquivos não contiverem novas linhas, você poderá evitar várias chamadas
grep
fazendo com que grep imprima os nomes dos arquivos correspondentes e conte os resultados.O número de correspondências é
"${#matches[@]}"
.Pode haver uma maneira de usar
grep --null -lw
aqui, mas não sei como analisar a saída . O Bashvar=( array elements )
não tem como usar um\0
delimitador em vez de\n
. Talvez omapfile
builtin do bash possa fazer isso? Mas provavelmente não, porque você especifica o delimitador com-d string
.Você poderia
count=$(grep -l | wc -l)
, mas então você tem dois processos externos, para que você possa executar apenasgrep
nos dois arquivos separadamente. (A diferença entre a sobrecargagrep
versus awc
inicialização é pequena em comparação com o material fork + exec + linker dinâmico para iniciar um processo separado).Além disso,
wc -l
você não descobre qual arquivo corresponde.Com os resultados capturados em uma matriz, isso já pode ser o que você deseja ou, se houver exatamente 1 correspondência, é possível verificar se foi a primeira entrada ou não.
$matches
é uma abreviação de${matches[0]}
, o primeiro elemento da matriz.fonte
-z
, não-0
, oops. Sim, isso faria o grep imprimir os nomes de arquivos separados por\0
como eu já mencionei na resposta, mas como você pode obter o bash para analisar isso? Você não pode definirIFS=$'\0'
, ou basicamente fazer qualquer outra coisa comfind -print0
saída de estilo diretamente com o bash.grep
s para lidar de qualquer maneira.mapfile -d $'\0'
funciona, mas substitui as novas linhas por espaços (não tentei ajustarIFS
).