Для этой работы я бы выбрал awk. Код ниже работает только для действительных данных 9 чисел в строке. Пустые строки, строки с числами больше или меньше 9 и строки с буквами игнорируются.
$ cat account
876251251
716126181
888281211
asdferfggggg
666615211
787878787
123456789123
111212134
$ cat customer
876251251
716126181
eeeeeeeee
792342108
792332668
666615211
760332429
791952441
676702288
$ awk '/^[0-9]{9}$/{a[$0]++;b[$0]="found only in " FILENAME}END{for (i in a) if (a[i]==1) print i,b[i]}' account customer |sort -k2
111212134 found only in account
787878787 found only in account
888281211 found only in account
676702288 found only in customer
760332429 found only in customer
791952441 found only in customer
792332668 found only in customer
792342108 found only in customer
Основываясь на ответе taiyu с использованием inotifywait
, я создал node.js
решение этой проблемы... Требовалось больше подробностей, чем я ожидал, когда спрашивал об этом. Извините, если это не то место для публикации кода node.js, но асинхронный характер языка упростил мне задачу... Мое решение следующее:
const fs = require('fs');
const spawn = require("child_process").spawn;
const file='/home/user/hugefile.csv';
let counter = 0; // counter used for identifying how many times the file was opened and closed by a different program
const child = spawn('/bin/bash', [ '-c', `inotifywait --format=%e -q -m -e access,close ${file}` ])
child.stdout.on('data', (data) => {
let line = data.toString().split('\n').filter(item => item); // get events inside a javascript array and filter empty values
// loop through the inotify events
line.forEach(function(event) {
if ( event === "ACCESS" )
counter++;
else if ( event === "CLOSE_NOWRITE,CLOSE" )
counter--;
// asynchronous function that checks the value of counter after 10 seconds
async function timer() {
await sleep(10000);
console.log(counter);
if ( counter === 0 ){
fs.unlinkSync(file); // erase file
console.log("tmpfile erased!")
process.exit();
}
}
timer();
});
});
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
По сути, я использовал inotifywait
как основу для решения проблемы... Мне просто нужно выполнить этот скрипт после создания временного файла, и он удалит файл после того, как все другие программы закончат чтение файла (после 10 секунд ).
OBS :Проблема, которую я пытаюсь решить с помощью bash
, заключается в том, что когда я запускаю функцию как процесс с помощью &
, я теряю контроль над новыми значениями глобальных переменных внутри этой функции. Так что я не смог получить состояние counter
, используя ту же логику, которую я использовал для node.js
... Если кто-то знает обходной путь для этого, не стесняйтесь писать в комментариях здесь.:)
Используя inotifywait, вы можете добавить в свои скрипты, которые обращаются к файлу, следующее.
if ! inotifywait $FILE -t $SECONDS >/dev/null 2>&1
then rm $FILE
fi &
Сценарий порождает процесс, ожидающий, пока кто-то не получит доступ к $FILE.
если что-то происходит, он ничего не делает и выходит.
если время ожидания истекло после $SECONDS, он удалит файл
альтернативно используя отдельный скрипт, который вы запускаете при создании файла
while inotifywait $FILE -t $SECONDS >/dev/null 2>&1
do sleep 1
done
rm $FILE
он будет зацикливаться при доступе к файлу,
если ничто не обращается к нему в течение тайм-аута, он ломает и удаляет файл.