Используйте скрипт awk, как показано ниже:
NR == FNR {
strt=1
}
NR != 1 && FNR ==1 {
strt=0
}
strt == 1 {
fileB[FNR"_"$1$2$3$4]=$0
}
strt == 0 {
fileA[$2$9$3$4]=$0
}
END {
for (i in fileB) {
split(i,arry,"_")
if (fileA[arry[2]] != "") {
print fileA[arry[2]] > "fileC"
system("sed -i \"/"fileA[arry[2]]"/d\"
fileA")
}
else {
print fileB[i] > "fileD"
}
}
Сначала мы считываем строки из каждого файла в два массива, файл A и файл B, и оба имеют один и тот же ключ, т. е. «Baillie2011DonorAH84452925». Мы перебираем каждую запись в массиве fileB и проверяем наличие соответствующей записи в файле A. Если он существует,добавить запись в файл C через перенаправление печати, а также выполнить команду sed через системную функцию awk (ОСТЕРЕГАЙТЕСЬ -системная функция сопряжена с риском внедрения кода, поэтому оцените риск соответствующим образом )Если совпадений нет, выведите строка в файлеD.
Действие с:
awk -f awkscriptfile fileB fileA
Согласитесь с другими плакатами, что вам не следует использовать ls
для такого анализа, но, поскольку то, что у вас есть, подходит для того, что вы делаете, не можете ли вы просто использовать переключатель -d в своем ls
для получения полного пути к каталогу?
Нет причин менять рабочий каталог, если только вы не выполняете гораздо больше работы. Обратите внимание, что вам нужно будет добавить этот подстановочный знак.
ssh user@host "ls -d1tr /data/* | head -n -2 | xargs -d '\n' rm -f --"
Вы не можете комбинировать команду scp
и команды оболочки в одном и том же выполнении. Лучшее, что вы можете сделать, это:
scp -i LightsailDefaultKey-eu-west-2.pem -r ubuntu@xxx.xxx.xxx.xxx:/data/ /local/data && \
ssh -i LightsailDefaultKey-eu-west-2.pem -r ubuntu@xxx.xxx.xxx.xxx:/data/ /local/data bash -c "cd /data; ls -1tr | head -n -2 | xargs -d '\n' rm -f --"
обратите внимание, что я использую &&
, чтобы гарантировать, что ssh не запустится, если scp не завершится успешно -в противном случае вы удалите файлы, которые еще не синхронизировали.
Используйте find
вместо ls
. См. Почему не разборls
(и что делать вместо )? .
заключите команды, которые вы хотите запустить в удаленной системе, в кавычки (, но обратите внимание, что могут возникнуть трудности с вложенными кавычками )или в этом документе.
напр. используя версии GNU find
, sort
, head
иcut
:
ssh -i LightsailDefaultKey-eu-west-2.pem ubuntu@xxx.xxx.xxx.xxx \
'find /data/ -maxdepth 1 -type f -printf "%Ts\t%p\0" | sort -z -nr |
head -z -n 2 | cut -z -f2 | xargs -0r rm -f --'
Обратите внимание, что я использовал двойные -кавычки вокруг строки формата printf вместо одинарных -. Это потому, что они встроены в одинарные кавычки -, обертывающие весь конвейер команд, выполняемых ssh
. Вместо этого я мог бы использовать -printf '\''%Cs\t%p\0'\''
, но (, так как здесь нет риска интерполяции переменных и т. д. ), проще использовать двойные -кавычки.
Формат -printf
печатает отметку времени последнего -измененного файла (в секундах, начиная с эпохи, легко сортируемую как число по sort -z -rn
), табуляции и полному имени файла. cut
удаляет метку времени и вкладку, оставляя только имя файла для передачи в xargs
.
Альтернативой может быть использование heredoc:
ssh -i LightsailDefaultKey-eu-west-2.pem ubuntu@xxx.xxx.xxx.xxx <<-'EOF'
find /data/ -maxdepth 1 -type f -printf '%Ts\t%p\0' | sort -z -nr |
head -z -n 2 | cut -z -f2 | xargs -0r rm -f --
EOF