
supongamos que si un script de shell agrega datos a un archivo.txt como
1...........
2...........
3.............
4.............
5..............
Ahora quiero otra secuencia de comandos que pueda verificar los datos nuevos agregados al archivo.txt en cinco segundos, no los datos completos.
No sé si existe alguna opción tail -f
que muestre datos completos.
para entender algo como tail -5 file.txt
donde -5 no es el número de líneas sino el número de segundos.
NOTA: No quiero perder ningún dato cada vez, debería darme los datos desde donde salió la última vez. Esto es importante.
Respuesta1
retail
es uncon estado tail
. Registra el número de inodo y el tamaño del archivo después de cada invocación, la siguiente invocación continúa donde lo dejó (opcionalmente también se ocupa de archivos rotados, razón por la cual se registra el inodo).
while true; do
retail myfile.log
sleep 5
done
A menos que los datos del archivo contengan marcas de tiempo (podría serlo, si es a través de syslog) o algún ID creciente y monótono, debe tener algún estado externo que retail
utilice el tamaño del archivo.
Suponiendo que el archivo solo se agrega y se vacía línea por línea, retail
no se perderán datos. También debería ser más confiable que inspeccionar marcas de tiempo dentro de los datos, a menos que tengan alta precisión (por ejemplo, µs o mejor precisión).
retail
está escrito en C y parece similar a la sugerencia de @Ulrich Dangel de logtail
. Parece haber dos versiones distintas de eso, ambas implementadas en Perl, ninguna de las cuales he usado:
Respuesta2
Podrías extraer los últimos 5líneasdesde el script, tail -n 5
pero solo el último cambio en un archivo tiene una marca de tiempo, no hay una marca de tiempo para cada cambio. Si desea recuperar el últimonortesegundos, debes guardarlos por separado tú mismo.
Podrías cuantificar tus datos. Digamos que la escritura del script lo hace, en el bucle principal crea una función que se iniciará una vez por segundo:
CSEC=`date +%S`
if [ "x$CSEC" != "x$SAVEDSEC" ] ; then
mv f4.txt f5.txt
mv f3.txt f4.txt
mv f2.txt f3.txt
mv f1.txt f2.txt
echo $BUFFER > f1.txt
BUFFER=
SAVEDSEC=$CSEC
fi
y en el lugar donde escribe datos, por ejemplo, con echo
, también los agrega al búfer.
echo $DATA >file.txt
BUFFER=$BUFFER$DATA
(y las escrituras se almacenan en $BUFFER en lugar de escribirse en 'file.txt`)
En este caso, su secuencia de comandos podría funcionar cat f?.txt
para recuperar los últimos 5 segundos de datos.
Por supuesto, preste atención al bloqueo. Si un script se lee justo en medio de la operación de disco de otro script, los datos se dañarán.
Respuesta3
Esto debería hacer exactamente lo que te gustaría....
#!/bin/bash
#This is the file we want to capture data from
TAILFILE=/path/to/input.txt
#This is the file we want to append to
OUTFILE=/path/to/output.txt
#How many seconds we want to tail the file
SECONDS=5
tail -F $TAILFILE >> $OUTFILE &
PID=$!
sleep $SECONDS
kill $PID