Quiero buscar múltiples cadenas en dos archivos. Si se encuentra una cadena en ambos archivos, haga algo. Si se encuentra una cadena en un solo archivo, haga otra cosa.
Mis comandos son los siguientes:
####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
¿Es correcta la forma de negar y afirmar las declaraciones? pd Estoy usando KSH shell.
Gracias de antemano.
text-processing
awk
grep
ksh
Mareyes
fuente
fuente
Otra opción:
fuente
Nota:
((n++))
es una extensión ksh (también compatible conzsh
ybash
). En lash
sintaxis POSIX , necesitaría en sun=$((n + 1))
lugar.fuente
n=$((n++))
NUNCA cambiará el valor de n porquen++
es un incremento posterior : devuelve el valor actual de n, luego incrementa n; luego establece la variable al valor devuelto que era el n original.local IFS=$'\n'; matches=( $(grep -lw "$users" "$file1" "$file2") )
, y usecase "${#matches[@]" in
. @glenn: esta idea también se aplica a su respuesta, para evitar múltiples invocaciones degrep
. Instalarlogrep -l | wc -l
también funcionaría.Si sus nombres de archivo no contienen nuevas líneas, puede evitar múltiples invocaciones
grep
haciendo que grep imprima los nombres de los archivos coincidentes y cuente los resultados.El número de partidos es
"${#matches[@]}"
.Puede haber una forma de usar
grep --null -lw
aquí, pero no estoy seguro de cómo analizar la salida . Bashvar=( array elements )
no tiene una forma de usar un\0
delimitador en lugar de\n
. Tal vez bashtinmapfile
incorporado puede hacerlo? Pero probablemente no, porque especificas el delimitador con-d string
.Podría
count=$(grep -l | wc -l)
, pero luego tiene dos procesos externos, por lo que podría ejecutargrep
los dos archivos por separado. (La diferencia entre la sobrecarga de iniciogrep
y la dewc
inicio es pequeña en comparación con las cosas fork + exec + dynamic linker para iniciar un proceso por separado).Además, con
wc -l
usted no descubre qué archivo coincide.Con los resultados capturados en una matriz, eso podría ser lo que desea, o si hay exactamente 1 coincidencia, puede verificar si fue la primera entrada o no.
$matches
es la abreviatura de${matches[0]}
, el primer elemento de matriz.fuente
-z
, no-0
, vaya. Sí, eso obtendría grep para imprimir los nombres de archivo separados por\0
como ya mencioné en la respuesta, pero ¿cómo puede hacer que bash analice eso? No puede establecerIFS=$'\0'
, o básicamente hacer cualquier otra cosa confind -print0
salida de estilo directamente con bash.grep
todos modos solo hay algunas cosas que tratar.mapfile -d $'\0'
funciona, pero reemplaza las nuevas líneas con espacios (no he intentado ajustarIFS
).