GNU parallel — это инструмент, который вам нужен. Автор, Оле Танге , здесь завсегдатай и написал несколько хороших ответов на вопросы об этом
.
Версия GNU xargs
из findutils
также имеет некоторые возможности для параллельного выполнения нескольких заданий. Вероятно, его проще использовать для простых задач, подобных вашей, но он далеко не так гибок и эффективен, как parallel
.
Например:
find. -maxdepth 1 -type f -name 'a_file_*' -print0 |
xargs -0r -L 1 -P 4 sh -c '/usr/bin/md5sum "$1" > "$1.md5sum"' {}
Будет запущено до 4 md5sum
заданий параллельно(-P 4
). Я также использовал опцию -L 1
, чтобы ограничить каждое задание обработкой одного имени файла за раз -без этого (, иначе было бы запущено только 1 задание с 1000 именами файлов)
Заголовок ("Как мне изменить только один символ в строке, если таких символов несколько?" )- это ваша попытка решения, но фактическая проблема объясняется в теле вопроса. Сравните XY задачу . Мой ответ касается тела.
IFS=- read n1 n2 n3
Это заполнит переменные n1
, n2
и n3
фрагментами пользовательского ввода; соответственно:
-
, -
и вторым -
, -
(, включая оставшиеся -
символы, если таковые имеются ). Затем вы можете использовать printf
, чтобы распечатать их в любом формате, например, в формате.
printf '(%s) %s-%s\n' "$n1" "$n2" "$n3"
printf '%s%s%s\n' "$n1" "$n2" "$n3"
Вы можете быть либеральными в том, что вы принимаете и не требовать строгого формата. Пример в качестве функции оболочки:
get_phone_number() {
IFS= read -rp "Enter phone number (10 digits; additional dashes, spaces, whatever allowed): " p || return 1
# remove non-digits
p="$(tr -dc '0123456789' <<< "$p")"
# check if there is 10 of them
if [ "${#p}" -ne 10 ]; then
echo "Wrong number of digits. Aborting." >&2; return 2
else
n1="${p:0:3}"
n2="${p:3:3}"
n3="${p:6:4}"
fi
}
Вызвать get_phone_number
. Если функция выполнена успешно, используйте $n1
, $n2
и $n3
с printf
(, как указано выше ), или любым другим способом.
Вы понимаете, что создаете файл с именем phone
, верно? Также бессмысленно связывать echo
с cat
, вы могли бы (, но не должны )просто делатьecho "$phone" > phone
Я придумал следующее для вашего решения. Возможно, это не самый короткий метод, но он будет работать :
.#!/bin/bash
read -rp "Enter phone number (xxx-xxx-xxxx): " p
area_code=${p:0:3}
prefix=${p:4:3}
line=${p:8:4}
printf '%s\n%s\n' \
"($area_code) ${prefix}-${line}" \
"${area_code}${prefix}${line}"
Чтение может предложить пользователю ввести данные, чтобы мы могли исключить комбинацию echo
/ read
.
Затем мы используем расширение параметра , чтобы извлечь три части телефонного номера и распечатать их в двух требуемых форматах.
Обратите внимание, :это не выполняет никакой проверки работоспособности, поэтому пользователи могут вводить ложные данные и получать фиктивные выходные данные.
GNU sed
позволяет указать, какое вхождение шаблона (в строке )следует заменить:
Первый (по умолчанию)
echo AAAAA | sed 's/A/X/'
XAAAA
Все
echo AAAAA | sed 's/A/X/g'
XXXXX
я -й
echo AAAAA | sed 's/A/X/3'
AAXAA
Чтобы конкретно решить вашу проблему с помощью этого метода, вам потребуются две модификации вsed
:1 )изменить начало строки (^
), чтобы добавить открывающие круглые скобки, 2 )заменить первый тире на закрывающие скобки и пробел.
echo 123-123-1234 | sed 's/^/(/;s/-/) /'
(123) 123-1234
В качестве альтернативы, sed
позволяет сопоставлять шаблоны и сохранять их (по количеству вхождений ), заключая шаблон в круглые скобки. В выходной строке вы можете называть их по номеру:
echo 123-123-1234 | sed 's/\([0-9]\+\)-\([0-9]\+\)-\([0-9]\+\)/(\1) \2-\3/'
(123) 123-1234
Здесь [0-9]
соответствует цифре от 0 до 9,\+
означает одно или несколько вхождений предыдущей группы (Расширение GNU дляsed
)и \(<pattern>\)
сохранит шаблон и присвоит ему порядковый номер (, начиная с 1 для первого и так далее ). Таким образом, \([0-9]\+\)-
будет соответствовать одной или нескольким цифрам, за которыми следует тире, и запомнит цифровую часть.
В выводе \1
печатается первый сохраненный шаблон из совпадения (, т.е. [0-9]\+
... одна или несколько цифр перед тире. Затем мы просто используем три сохраненные группы цифр и форматируем их по своему усмотрению.