Я верю, что это сделает то, что вы хотите. Это было написано в ksh
для Linux, но будет работать с bash
или другими в большинстве версий Unix.
#!/bin/ksh
rm -f english.out
rm -f french.out
output=both
while read linein
do
echo $linein | grep HDR >/dev/null && output=both
echo $linein | grep English >/dev/null && output=english
echo $linein | grep French >/dev/null && output=french
echo $linein | grep TRL >/dev/null && output=both
case $output in
both)
echo "$linein" >> english.out
echo "$linein" >> french.out
;;
english)
echo "$linein" >> english.out
;;
french)
echo "$linein" >> french.out
;;
esac
done < data.txt
Для пояснения:
- Удалите старые выходные файлы при запуске.
- Установите для переменной
output
оба значения.
- Цикл while читает файл
data.txt
, по одной строке за раз
в переменную linein
. (Цикл while...done
имеет ввод, перенаправленный из файла data.txt
.)
- (Некоторые люди сочтут это неопрятным) Мы повторяем каждую строку в grep, отбрасывая вывод и сохраняя только статус выхода. Если статус выхода успешен, мы устанавливаем вывод. Если статус выхода равен false, мы не меняем вывод. Это позволяет нам отправлять записи NFD в то же место, что и предыдущая запись.
- Случай переключается между различными значениями вывода, чтобы решить, куда отправить вывод. Я ожидаю, что вы знаете, что
>>
означает добавление вывода в файл. Соблюдайте кавычки вокруг $linein
. Если их там нет, вы не сохраните пробелы во входных данных. Это не имеет значения в вашем случае.
Если вы хотите искать только английский или французский в поле 5, оно становится более сложным (и не работает с bash
(или со старыми версиями ksh
)):
#!/bin/ksh
rm -f english.out
rm -f french.out
output=unknown
while read linein
do
if [[ $linein == {15}(\d)\;HDR* || $linein == {15}(\d)\;TRL* ]]
then
output=both
else
if [[ $linein == {15}(\d)\;+([A-Z])\;+([^\;])\;+([^\;])\;+([^\;])\;* ]]
then
case ${.sh.match[5]} in
English)
output=english
;;
French)
output=french
;;
*)
echo "unknown language: ${.sh.match[5]}" >&2
output=both
;;
esac
fi
fi
case $output in
both)
echo "$linein" >> english.out
echo "$linein" >> french.out
;;
english)
echo "$linein" >> english.out
;;
french)
echo "$linein" >> french.out
;;
*)
echo "Unknown output: $output" >&2
;;
esac
done < data.txt
${.sh.match[5]}
содержит подвыражение # 5 в строке соответствия (части внутри скобки ()
).
Вытянуть подвыражения с помощью awk
проще, но это чистое ksh
решение.