Если ваша оболочка их поддерживает, вы можете использовать ассоциативный массив для первого случая:
declare -A list=([john]="john@gmail.com" [doe]="doe@outlook.com" [jenny]="jenny@another.domain")
for i in "${!list[@]}"; do
echo "Dear $i, email text" | mail -s "Hello $i" "${list[$i]}"
done
Для второго случая цикл while:
while IFS=, read -r i j; do
echo "Dear $i, email text" | mail -s "Hello $i" "$j"
done < file.csv
(это предполагает, что ваш файл правильно отформатирован в формате CSV без строки заголовка ).
Здесь немного по-другому:
Сохранить вывод в новые файлы:
for file in *fa; do
sed -E 's|^\s*(>.{10,}.*)/.*|\1|' "$file" > "$file.fixed";
done
Отредактируйте файлы на месте:
sed -i -E 's|^\s*(>.{10,}.*)/.*|\1|' *.fa
Параметр -E
включает расширенные регулярные выражения. Это позволяет нам использовать ()
для захвата и {}
для повторов без необходимости экранировать их. Я также изменил разделитель на |
для ясности и добавил примечание^\s*
(о том, что это может не поддерживаться вашим sed
; если это не так, вы можете использовать ^ *
вместо ), так как иногда вы можете иметь пробел перед >
в файлах fasta.
Затем хитрость заключается в том, чтобы сопоставить >
, за которым следуют 10 или более символов до /
, захватить эти символы скобками, чтобы они стали \1
, и заменить всю строку только совпадающей частью.
Обратите внимание, что будет найден самый длинный отрезок из >10 символов до последнего /
. Итак, если в одной строке несколько /
, будут сохранены все, кроме последнего. Например:
$ echo ">header1_some_extra_data_here/1-1000/foo/bar/baz" |
sed -E 's|^\s*(>.{10,}.*)/.*|\1|'
>header1_some_extra_data_here/1-1000/foo/bar
Чтобы избежать этого и удалить все после первого /
, если вы уже сопоставили 10 символов, используйте:
sed -E 's|^\s*(>.{10}[^/]*)/.*|\1|'