Если у вас есть GNU sed, вы можете использовать нестандартную -команду R
для чтения и вставки индексов из предварительно -сгенерированной последовательности со вторым вызовом sed для переупорядочения результата:
printf '%d\n' {5..100} | sed '/^Keyword/R /dev/stdin' file |
sed '/^Keyword/{N; s/Keyword "\([^"]*\)"\n\(.*\)/Keyword "\2 - \1"/}'
Однако я бы предложил использовать perl
или awk
для этой задачи вместо -, например
awk -v k=5 '/^Keyword/ {sub(/^Keyword \"/, sprintf("Keyword \"%d - ", k++))} 1' file
Здесь есть несколько вопросов.
#!/bin/sh
шебанг. Если вы сделаете его исполняемым с помощью chmod +x sample.sh
, вы можете вызвать его как./sample.sh...
'|'
`...`
на $(...)
и удален символ пробела в присваивании переменной NR>1
для пропуска первой (строки заголовка )входного файла !~
[[...]]
не является допустимой конструкцией sh
и была изменена на [...]
в сочетании с оператором проверки -n
, что верно, если следующая строка не -пуста. Я также добавил $val
к выводу echo
, чтобы увидеть, где произошла ошибка, и напечатал $n
вместо $1
. Измените это обратно по мере необходимости. Вывод поступает на стандартный вывод (>&2
), и сценарий завершается с нулевым статусом выхода, отличным от -, что указывает на сбой.
Модифицированный скрипт:
#!/bin/sh
val=$( awk -F'|' -v n="$1" -v m="$2" 'NR>1 && $n !~ "^" m "$"{ print $n }' sample_file.txt )
if [ -n "$val" ]; then
echo "column value is having unexpected format: $val" >&2
exit 1
fi
Ваши регулярные выражения не соответствуют адресам электронной почты, если вы сопоставляете полное поле с ^
и $
,
например, сработает '[a-z]+@gmail.com'
. Не забудьте указать хотя бы параметр регулярного выражения, чтобы предотвратить возможную интерпретацию оболочки.
Пробный запуск:
$./sample.sh 3 '[a-z]+@gmail.com'
column value is having unexpected format: xyz
$./sample.sh 3 'xyz'
column value is having unexpected format: src@gmail.com
rec@gmail.com
Опираясь на отличный ответ @Freddy, вы можете awk
регистрировать ошибки, найденные во входном файле, в STDERR, а затем перенаправлять STDERR в файл журнала с 2>
(, который вы можете записать непосредственно в файл журнала ошибок из awk
, если хотите, но более гибко использовать оболочку для перенаправления STDERR ).
awk -F'|' -v n="$1" -v m="$2" '
FNR>1 && $n !~ "^" m "$" {
print NR ":" $0 > "/dev/stderr"
}' input.txt 2> error.log
Вы также можете заставить его возвращать количество ошибок в STDOUT, которое будет захвачено для $val
переменной оболочки:
#!/bin/sh
val=$(awk -F'|' -v n="$1" -v m="$2" '
FNR>1 && $n !~ "^" m "$" {
printf "%s:%s:%s\n", FILENAME, FNR, $0 > "/dev/stderr"
count++
}
END {print count}' sample_file.txt 2> errors.log
)
if [ "$val" != 0 ]; then
echo "$val errors found in input:"
cat errors.log
exit 1
fi
Например:
$./sample.sh 3 xyz
2 errors found in input:
sample_file.txt:2:1|file1.txt|src@gmail.com
sample_file.txt:3:2|file2.txt|rec@gmail.com
Примечание:awk
будет использовать -
для FILENAME, если входные данные поступают из STDIN, поэтому журнал ошибок будет выглядеть примерно так:
-:4:3|file3.txt|xyz