noatime
deshabilita las actualizaciones de tiempo de acceso implícitas (aquellas que ocurren como un efecto secundario -de una operación en un archivo ); no afecta las actualizaciones de tiempo de acceso explícito (donde un programa pide explícitamente al sistema operativo que actualice el tiempo de acceso de un archivo ). Cuando touch
un archivo, está solicitando explícitamente actualizar los tiempos de acceso y modificación, y eso es lo que sucede.
Puede touch
un archivo sin cambiar el tiempo de acceso, utilizando la opción -m
; sólo se actualizará la hora de modificación.
find
+awk
раствор:
find./backup -type f -exec \
awk 'NR == 1{ if (/StockID.*SellPrice/) print FILENAME; exit }' {} \;
В случае, если порядок ключевых слов может быть другим -, замените шаблон /StockID.*SellPrice/
на /StockID/ && /SellPrice/
.
В случае большого количества файлов более эффективной альтернативой будет (обработка сразу нескольких файлов;общее количество вызовов команды будет намного меньше, чем количество совпадающих файлов):
find./backup -type f -exec \
awk 'FNR == 1 && /StockID.*SellPrice/{ print FILENAME }{ nextfile }' {} +
egrep
+awk
:
egrep -Hrn 'StockID|SellPrice'./backup | awk -F ':' '$2==1{print $1}'
С GNU grep
или совместимым:
grep -Hrnm1 '^'./backup | sed -n '/StockID.*SellPrice/s/:1:.*//p'
Рекурсивный grep напечатает первую строку каждого файла и напечатаетfilename:1:line
без чтения всего файла (флаг -m1
должен привести к выходу при первом совпадении )и sed
напечатает filename
, где часть line
соответствует образцу.
Это не удастся с именами файлов , которые сами содержат :1:
или символы новой строки, но на этот риск стоит пойти вместо того, чтобы создавать медленную комбинацию find
+ awk
, которая выполняет другую процесс для каждого файла.
Чтобы избежать запуска одной команды для каждого файла и чтения всех файлов, с помощью GNUawk
:
(unset -v POSIXLY_CORRECT; exec find backup/ -type f -exec gawk '
/\<StockID\>/ && /\<SellPrice\>/ {print FILENAME}; {nextfile}' {} +)
Или сzsh
:
set -o rematchpcre # where we know for sure \b is supported
for file (backup/**/*(ND.)) {
IFS= read -r line < $file &&
[[ $line =~ "\bStockID\b" ]] &&
[[ $line =~ "\bSellPrice\b" ]] &&
print -r $file
}
или:
set -o rematchpcre
print -rl backup/**/*(D.e:'
IFS= read -r line < $REPLY &&
[[ $line =~ "\bStockID\b" ]] &&
[[ $line =~ "\bSellPrice\b" ]]':)
Или с bash
в системах, где встроенные расширенные регулярные выражения поддерживают \<
, \>
операторы границ слов (в других, некоторые другие, вы также можете попробовать [[:<:]]
/ [[:>:]]
или \b
вместо):
RE1='\<StockId\>' RE2='\<SellPrice\>' find backup -type f -exec bash -c '
for file do
IFS= read -r line < "$file" &&
[[ $line =~ $RE1 ]] &&
[[ $line =~ $RE2 ]] &&
printf "%s\n" "$file"
done' bash {} +