Вот быстрая острота, которую можно ввести в терминале:
find . -name "*.wav" -print0 | while read -d $'\0' file; do neroAacEnc -2pass -q 1 -if "$file" -of "${file%wav}m4a"; done
Можно также использовать ffmpeg, как @slm предполагает,
find . -name "*.wav" -print0 | while read -d $'\0' file; do ffmpeg -i "$file" -c:a libfdk_aac -vbr 3 output.m4a "${file%wav}m4a"; done
Я не уверен, как neroAacEnc выдерживает сравнение с ffmpeg, но я знаю, что ffmpeg совершенствуется довольно популярный у многих пользователей Linux.
Объяснение
find
программа, которая возвращает пути к файлам, которые соответствуют определенному свойству файла, в этом случае имя файла. Если бы все, что Вы хотели знать, было тем, какие .wav файлы находятся в подкаталогах Вашего текущего пути, то Вы сделали бы find . -name "*.wav"
. Обычно это производит каждый файл на новой строке. -print0
заставляет его разделить соответствия с нулевым символом вместо этого. Это допускает правильное обращение имен файлов с пробелами, когда мы передаем вывод следующим командам.
|
символ известен как канал. Это говорит оболочке брать вывод команды слева и передавать его как вход к команде справа, в этом случае, read
команда в while
цикл.
read
команда используется для взятия вывода find
и присвойте его переменной, "файлу". Обычно это присвоило бы значения, чтобы "зарегистрировать" каждое слово за один раз, но -d $'\0'$
заставляет присвоения быть разграниченными нулевым символом (соответствие, как мы разграничили файлы в find
при помощи -print0
флаг).
Причины циклов с условием продолжения read
многократно присваивать значения "файлу" для каждого имени файла соответствия. do
и done
часть стандартного синтаксиса удара некоторое время цикл:
while <something is true>; do
<run some commands>
done
В этом случае, наш "выполненный некоторая команда" также ffmpeg
или neroAacEnc
. В каждом из случаев, входной файл (т.е. $file
) указан с переменной "файла", с которой мы присвоились read
, и выходной файл (т.е. ${file%wav}w4a
) управление этой переменной, которая позволяет нам указывать другое имя для вывода. Обычно $file
или ${file}
оценил бы к названию файла, сказал бы некоторый song.wav. %
говорит для отключения от права на переменную любой последовательности, соответствующей символам [1] направо от %
(т.е. "wav"). Так ${file%wav}
оценил бы к некоторой песне., и затем "m4a" там, чтобы быть новым концом имени файла: некоторая песня m4a.
[1] Я говорю "символы" здесь для простоты. Последовательность направо от %
могло быть регулярное выражение. Например, если мы сказали ${file%w*v}
и переменная была некоторой песней w1234v, она также оценит к некоторой песне..
С помощью sed
можно использовать диапазон и q
uit вход при одном завершении:
sed '/^182$/p;//,/^ABC$/!d;/^ABC$/!d;q'
Аналогично w/ GNU grep
можно разделить вход между двумя grep
s:
{ grep -nxF -m1 182; grep -nxF -m1 ABC; } <<\IN
123
XXY
214
ABC
182
558
ABC
856
ABC
IN
. ... который печатает ...
5:182
2:ABC
... что означает, что первый grep
нашел -F
ixed-строчный буквальный, -x
целую строку 182 , совпадающую с 5 строками от начала его считывания, и вторая обнаружила, что аналогично набранная ABC совпадает с 2 строками от начала чтения - или с 2 строками после первого grep
quit чтения на 5-й строке.
Из man grep
:
-m NUM, --max-count=NUM
Stop reading a file after NUM matching
lines. If the input is standard input from
a regular file, and NUM matching lines are
output, grep ensures that the standard input
is positioned to just after the last
matching line before exiting, regardless of
the presence of trailing context lines.
This enables a calling process to resume a
search.
Я использовал этот документ для воспроизводимой демонстрации, но вы, вероятно, должны это сделать:
{ grep ...; grep ...; } </path/to/log.file
Он также будет работать с другими оболочками составных командных конструкций, таких как:
for p in 182 ABC; do grep -nxFm1 "$p"; done </path/to/log.file
Изменение Perl, которое вы могли бы использовать:
perl -nle 'm/182/../ABC/ and print' file
... который печатает линии в диапазоне соответствия.
Если вы подаете файл, содержащийся более одного диапазона соответствия, вы можете ограничить вывод только на первый диапазон, изменяя разделитель /
в ?
perl -nle 'm?182?..?ABC? and print'
> strace -c -f -e trace=fork,vfork,clone,execve,execl bash -c 'ls -ld /etc;sleep 1'
Process 15683 attached
drwxr-xr-x 1 root root 5540 10. Jan 02:08 /etc
Process 15684 attached
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
0.00 0.000000 0 2 clone
0.00 0.000000 0 3 execve
------ ----------- ----------- --------- --------- ----------------
100.00 0.000000 5 total
> strace -c -f -e trace=fork,clone,execve bash -c '(foo=bar;ls -ld /etc);sleep 1'
Process 15730 attached
Process 15731 attached
drwxr-xr-x 1 root root 5540 10. Jan 02:08 /etc
Process 15732 attached
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
0.00 0.000000 0 3 clone
0.00 0.000000 0 3 execve
------ ----------- ----------- --------- --------- ----------------
100.00 0.000000 6 total
-121--166960- Использование GREP
с использованием Perl-совместимых регулярными выражениями ( PCREGREP
):
pcregrep -Mo '182(.|\n)*?\KABC'
Опция -M
Разрешить шаблон соответствовать Более одной строки, и \ k
не включает в себя сопоставленные шаблон (до этой точки) в вывод. Вы можете удалить \ k
, если вы хотите иметь весь регион в результате.
> awk '/^182$/ { startline=1; }; startline == 0 { next; }; /^ABC$/ { print "line " NR ": " $0; exit; }' file
line 7: ABC
приклеивая только grep
и добавляя хвост
и разрез
, вы могли бы...
grep для номера линии первого совпадения 182
:
grep -m 1 -n 182 /var/log/file |cut -f1 -d:
Используйте это, чтобы grep для всех ABC
только после первой линии совпадения выше, используя tail
's -n +K
, чтобы вывести после линии K'th. Все вместе:
tail -n +$(grep -m 1 -n 182 /var/log/file |cut -f1 -d:) /var/log/file | grep ABC
Или добавьте -m 1
снова, чтобы найти только первое совпадение ABC
tail -n +$(grep -m 1 -n 182 /var/log/file|cut -f1 -d:) /var/log/file|grep -m 1 ABC
Ссылки:
man
pages
https://stackoverflow. com/questions/6958841/use-grep-to-report-back-only-line-numbers
Другой вариант:
grep -n -A99999 "182" /var/log/file|grep -n -m1 "ABC"
Флаг -An greps n строк после совпадения, а 99999 - просто для того, чтобы мы ничего не пропустили. В файлах большего размера должно быть больше строк (проверьте с помощью "wc -l").
Оператор диапазона ,
может быть использован здесь:
< yourfile \
sed -e '
/182/,/ABC/!d
//!d;=;/ABC/q
' | sed -e 'N;s/\n/:/'
Оператор диапазона ...
в тандеме с оператором match-only-once m??
может быть использован здесь в Perl
perl -lne 'm?182? .. m?ABC? and print "$.:$_" if /182/ || /ABC/' yourfile