Эта задача легче с GNU sed
:
$ sed -i 's/ali/ALI/' file.txt
потому что tr
воздействует на наборы символов, а не строки.
Для предотвращения нежелательных замен при повторении попытайтесь указать точное положение слова, которое будет заменено и или регулярное выражение, которое соответствует только строке, которой Вы интересуетесь:
$ printf "cali\nali\nwali\nmali.\n" | grep -E '^ali' | tr ali ALI
ALI
Всякий раз, когда у вас есть несколько процессов, выводящих на один терминал (или файл) параллельно, вы рискуете, что их вывод будет рассеян (если только вы не договоритесь о какой-нибудь блокировке или использовании низкоуровневых системных вызовов, таких как запись
в файлы, открытые только в режиме append-only).
В качестве первого шага вы можете минимизировать, но не полностью устранить проблему, если каждый вызов оболочки будет использовать замену команды : запустите команду whois
в качестве подпроцесса, перехватив ее вывод, а затем выведите все вместе в одну операцию printf
.
xargs -0 -n 1 -P 3 -I %% sh -c 'printf "\n%s\n%s\n%s\n" " 44rBegin whois record -- " "$(whois -h whois.arin.net %%)" " 44rEnd whois record -- "'
Еще лучше, если у вас есть программа flock
, вы можете использовать ее для блокировки каждого вызова к этой комбинированной printf
:
xargs -0 -n 1 -P 3 -I %% sh -c 'who="$(whois -h whois.arin.net %%)"; flock /tmp/who.lock printf "\n%s\n%s\n%s\n" " 44rBegin whois record -- " "$who" " 44rEnd whois record -- "'
] В этом конкретном случае вы передаете []-P 3[
] в []xargs[
]. [
-P max-procs
Run up to max-procs processes at a time; the default is 1. If max-procs is
0, xargs will run as many processes as possible at a time. Use the -n op‐
tion with -P; otherwise chances are that only one exec will be done.
]
[] Поскольку вы выполняете их параллельно, все они будут записывать свои результаты одновременно.[
] [] Если бы вы скопировали эту команду откуда-то еще, я бы порекомендовал вам провести исследование, чтобы понять, что это за команда, которую вы копируете. Иначе это может быть опасно.[
]Да, выход смешивается из-за xargs -P
. Вы выполняете несколько подпроцессов параллельно, и нечего координировать их вывод: они все пишут вывод, когда хотят, и все перемешивается.
Используйте GNU Parallel, который является гораздо более мощным инструментом для выполнения той же работы, что и xargs -P
. По умолчанию используется групповой вывод из каждого задания вместе.
echo "$1" | parallel -t -P 3 sh -c 'echo "\n 44rBegin whois record -- \n"; whois -h whois.arin.net $0; echo "\n 44rEnd whois record -- \n"'
Инструментов параллелизма оболочки меньше, чем пруд пруди. Я лично написал 3 из них. Самый последний находится наhttp://stromberg.dnsalias.org/~strombrg/coordinate/. Его можно проверить и установить с помощью:
svn checkout http://stromberg.dnsalias.org/svn/coordinate/trunk/ coordinate && cd coordinate && make install
Вы можете получить один файл на каждый IP-адрес с помощью:
coord-xargs-like \
-0 \
--max-args 1 \
whois -h whois.arin.net \
| coordinate \
--use-threads \
--commands-file /dev/stdin \
| coord-to-files --to-stdout --directory results/.
По умолчанию будет использоваться параллелизм, равный количеству ядер ЦП в вашей системе (, включая гиперпотоки ).
Вы получаете текущие обновления того, что выводится, по мере выполнения команд, и по одному файлу на команду в каталоге результатов. Вывод не перемешан, потому что координата использует блокировку.
Обратите внимание, что я не упомянул кадрирование результата. С одним файлом на whois он вам больше не нужен.
Также обратите внимание, что с одним файлом результатов для каждой команды вы можете использовать такие инструменты, как equivs3e, для быстрого и удобного устранения дубликатов при просмотре выходных данных :http://stromberg.dnsalias.org/~strombrg/equivalence-classes.html
find results/ -type f -print0 | equivs3e -0 --delete-newer