Вы ищете файлы длиной 9 байт, восемью символами и новой строкой. Это предполагает, что вы ищете только однобайтовые символы -.
find. -type f -size 9c -exec grep -l -E '^.{8}$' {} +
Это находит все обычные файлы в текущем каталоге или ниже, которые имеют длину ровно 9 байт. Чтобы убедиться, что они содержат только одну строку, мы выполняем над ними grep
и пытаемся сопоставить строку, содержащую ровно восемь символов. Мы позволяем grep
выводить имена соответствующих файлов с опцией -l
.
Сначала давайте очистим ваш существующий скрипт:
1 )Аргумент -i
для grep предназначен для строчного алфавитного сравнения, поэтому нет смысла использовать его для чисел. Так что просто избавьтесь от -i
из grep -i '05' 0310*
.
2)" "
- это значение FS по умолчанию для awk, поэтому вам не нужно указывать это с помощью -F " "
-, просто избавьтесь от этого тоже.
3 )Номера полей ввода не обязательно должны состоять из 2 -цифр, и их не нужно заключать в круглые скобки, чтобы разграничить их, поэтому каждый $(01)
и т. д. может быть просто $1
и т. д.
4 )Вам не нужен grep, когда вы используете awk, так что:
grep '05' 0310* |
awk '{print $1, $2, $5, $6}' |
grep -i am > Dealers_working_during_losses.txt
можно записать как просто:
awk '/05/{$0=$1 OFS $2 OFS $5 OFS $6; if (tolower($0) ~ /am/) print}' 0310* > Dealers_working_during_losses.txt
Теперь исправим существующие ошибки:
5)/05/
найдет05
в любом месте в записи (в виде поля минут, например ), но вы хотите найти его только в начале записи, так как именно там указана спецификация часов существует так изменить, что на /^05/
.
6 )Точно так же, как и grep -i am
, tolower($0) ~ /am/
найдет am
в любом месте записи (в имени человека, например ), но вы хотите найти его только тогда, когда это 2-е поле в записи, измените его наtolower($2) == "am"
Теперь у нас есть эта команда:
awk '/^05/{$0=$1 OFS $2 OFS $5 OFS $6; if (tolower($2) == "am") print}' 0310* > Dealers_working_during_losses.txt
но так как мы тестируем $2
только для утра или вечера, нам не нужно сначала создавать совершенно новую запись ($0 )перед тестированием, а затем печатать ее, и вместо этого мы можем сделать:
awk '/^05/{if (tolower($2) == "am") print $1, $2, $5, $6}' 0310* > Dealers_working_during_losses.txt
, который мы можем записать более идиоматически как:
awk '/^05/ && (tolower($2) == "am") {print $1, $2, $5, $6}' 0310* > Dealers_working_during_losses.txt
Теперь о том, как создать сценарий оболочки, который принимает аргументы для всех значений. Это будет:
#!/usr/bin/env bash
awk -v time="$2" -v ampm="$3" '($0 ~ ("^"time)) && (tolower($2) == tolower(ampm)) {print $1, $2, $5, $6}' "$1"* > Dealers_working_during_losses.txt
, который, если предположить, что вышеизложенное хранится в исполняемом файле с именем foo
, который находится в вашем PATH
,вы бы назвали:
foo 0310 05 am
Единственное, что я считаю неочевидным -выше, это то, что нам пришлось использовать другой синтаксис для сравнения времени, когда мы перешли от проверки буквального значения(^05
)к строке, полученной путем объединения строки "^"
. ] со значением переменной time
, поскольку использование строки в контексте регулярного выражения требует от нас использования динамического регулярного выражения , что также означает, что ярлык /.../
для $0 ~ /.../
, который работает в постоянном регулярном выражении нельзя использовать сравнения, поэтому нам нужно также написать часть $0 ~
.