Передача аргумента в Grep для получения определенного результата

Вы ищете файлы длиной 9 байт, восемью символами и новой строкой. Это предполагает, что вы ищете только однобайтовые символы -.

find. -type f -size 9c -exec grep -l -E '^.{8}$' {} +

Это находит все обычные файлы в текущем каталоге или ниже, которые имеют длину ровно 9 байт. Чтобы убедиться, что они содержат только одну строку, мы выполняем над ними grepи пытаемся сопоставить строку, содержащую ровно восемь символов. Мы позволяем grepвыводить имена соответствующих файлов с опцией -l.

0
24.03.2020, 05:40
1 ответ

Сначала давайте очистим ваш существующий скрипт:

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 ~.

0
28.04.2021, 23:19

Теги

Похожие вопросы