$ cat file | python -c "import sys
for line in sys.stdin: l=line.rstrip('\r\n').split('\t'); print('\t'.join(l[:9]) + ''.join(l[9:]))
"
s/(([^\t]*\t){8})/\1\n/
h
s/[^\n]*\n//
s/\t//g
G
s/([^\n]*)\n([^\n]*)\n.*/\2\1/
Пример использования:
$ sed -r "s/(([^\t]*\t){8})/\1\n/;h;s/[^\n]*\n//;s/\t//g;G;s/([^\n]*)\n([^\n]*)\n.*/\2\1/" file
Пояснение:
Предположим, что файл
равен
a b c d e f g h i j k l
Разделителем в файле
является табуляция.
sed
читает текущую строку.
a b c d e f g h i j k l
s / (([^ \ t] * \ t) {8}) / \ 1 \ n /
разбивает строку на две части.
a b c d e f g h \ ni j k l
h
сохраняет пространство шаблонов в пространстве хранения.
abcdefgh \ ni jkl
abcdefgh \ ni jkl
s / [^ \ n] * \ n //
удаляет первую часть в шаблоне Космос.
i j k l
a b c d e f g h \ ni j k l
s / \ t // g
удаляет табуляции в пространстве шаблонов.
ijkl
a b c d e f g h \ ni j k l
G
добавляет \ n
и удерживает пространство к пространству шаблонов.
ijkl \ na bcdefgh \ ni jkl
abcdefgh \ ni jkl
s / ([^ \ n] *) \ n ([^ \ n] *) \ n. * / \ 2 \ 1 /
разделяет пространство шаблонов и заменяет его второй и первой частями без \ n
.
a b c d e f g h ijkl
a b c d e f g h \ ni j k l
sed
печатает пространство шаблонов.
Можно изменить код и удалить вкладки в средних столбцах:
s/(([^\t]*\t){3})(([^\t]*\t){4})(.*)/\1\n\3\n\5/
h
s/[^\n]*\n([^\n]*)\n.*/\1/
s/\t//g
G
s/([^\n]*)\n([^\n]*)\n([^\n]*)\n(.*)/\2\1\4/
До версии 5.0.8, zsh
не мог ждать уже мертвых заданий. Это было изменено в версии 5.0.8 в 2014 году. См. изменение там.
Здесь вы можете просто перенаправить stderr в /dev/null
, чтобы игнорировать проблему:
wait $pid 2> /dev/null
Обратите внимание, что в:
{ tee $tmpdir/orig | arbitrary_pipeline > $tmpdir/alt; } &
качестве оптимизации, zsh
не будет форкать дополнительный процесс для arbitrary_pipeline
, он будет выполнять его в том же процессе, что и тот, который запускает подшелл, запущенный в фоне.
paste
не завершится до того, как увидит EOF на своем stdin, его stdin - это труба, на другом конце которой пишет $pid
(и его дети, если таковые имеются). Таким образом, он не увидит eof, пока $pid
(и его дети) не закроет все свои файловые дескрипторы (обычно только stdout) на пишущем конце трубы. Если только $pid
явно не закроет свой stdout (что бывает очень редко), это произойдет только при выходе.
Это означает, что paste
в большинстве случаев не завершится до $pid
, но на всякий случай все же стоит выполнить wait
.
Обратите внимание, что здесь можно использовать coproc
, чтобы избежать временных fifos:
coproc arbitrary_pipeline
cat >&p | paste - /dev/fd/3 3<&p &
coproc : close
wait
(обратите внимание, что wait
также ожидает coproc
s).