У вас не может быть языкового стандарта, использующего UTF-16 в системе POSIX, поскольку он несовместим с языковым стандартом C.
С помощью GNU awk
вы можете:
LC_ALL=C awk -v RS='\n\0' -v ORS='\n\0' -F '[|]\0' '{print $1}'
То есть обрабатывать ввод как поток байтов, но устанавливать разделители записей и полей как их двухбайтовые кодировки UTF-16LE. .
Это не сработало бы, если бы входные данные содержали такие вещи, как:
<U+0AFF><U+FF00>
Что будет закодировано как FF0A00FF
(то есть содержит разделитель записей \ n \ 0
).
Преобразование в UTF-8 кажется единственным надежным вариантом. Однако вам не нужно использовать временный файл (здесь предполагается, что карта символов локали UTF-8)
< file.in iconv -f UTF-16LE |
awk -F'|' '{print $1}' |
iconv -t UTF-16LE > file.out
Поскольку никакой другой символ, кроме |
в UTF-8, не может содержать байт для |
(0x7c) (то же самое для новой строки или любого символа в переносимом наборе символов), вы также можете оптимизировать, используя локаль C для awk
или даже используя cut
:
< file.in iconv -f UTF-16LE -t UTF-8 |
LC_ALL=C cut -d '|' -f1 |
iconv -f UTF-8 -t UTF-16LE > file.out
С ed(1)
:
echo -e '/\$Elements\$/+1,/\$EndElements\$/-1d\n.-1r f2\nw' | ed -s f1
Подробно:
/\$Elements\$/+1,/\$EndElements\$ /-1
соответствует строкам между $Elements$
и $EndElements$
d
удаляет указанные строки . .-1
теперь является строкой выше $EndElements$
r f2
читает файл f2
w
записывает результаты.sed -e "
/$lead/,/$tail/!b
//!d
/$lead/r f2
" f1
$Elements$
1 65 71
2 32 87
3 39 98
4 41 63
$EndElements$
,
оператора запятой. b
, которая передает управление в конец кода sed для этой строки (s ). //!d
так как мы намерены заменить тело диапазона пользовательским файлом f2.