Я пытаюсь выполнить анализ каждого столбца файла с несколькими столбцами и использую вставку, чтобы объединить столбцы вместе. Я априори не знаю, сколько там столбцов, поэтому я использую «wc -w» и цикл для определения массива команд. Каждая команда является заменой процесса. Следующий скрипт показывает, что я пытаюсь, и вывод отображается после. Примечательно, что если я выведу массив команд на терминал, то с помощью мыши вырезай и вставляй его, он работает нормально, поэтому это должен быть порядок раскрытия переменных и подстановки процесса.
Короче говоря, мне нужно иметь подстановку процесса внутри переменной оболочки. Есть идеи? Заранее спасибо.
-------------- script.sh ----------------
#!/bin/bash
f="file.txt";
echo "File contents"
cat $f;
# simple solution
echo; echo "First try";
paste <(cat $f) <(tac $f)
# now define cmd[1] and cmd[2] and merge together with paste
echo; echo "Second try";
cmd[0]="paste";
cmd[1]="cat $f";
cmd[2]="tac $f";
${cmd[0]} <(${cmd[1]}) <(${cmd[1]})
# but what I really want is something like:
echo; echo "Third try";
cmd[1]="<(cat $f)";
cmd[2]="<(tac $f)";
${cmd[0]} ${cmd[1]} ${cmd[2]}
# or even better:
echo; echo "Fourth try";
${cmd[*]}
echo; echo "Show the array";
echo ${cmd[*]}
------------- вывод --------------------
$ ./scipt.sh
File contents
A B C
D E F
G H I
First try
A B C G H I
D E F D E F
G H I A B C
Second try
A B C A B C
D E F D E F
G H I G H I
Third try
paste: <(cat: No such file or directory
Fourth try
paste: <(cat: No such file or directory
Show the array
paste <(cat file.txt) <(tac file.txt)
$ paste <(cat file.txt) <(tac file.txt)
A B C G H I
D E F D E F
G H I A B C
$
В ответ на shellter приведем пример ввода.
7.74336e-08 7.30689e-08 0.359106 19.981796 -0.160611 0.027
7.74336e-08 7.30689e-08 0.363938 19.985069 0.041319 0.035
7.74336e-08 7.30689e-08 0.363133 19.982094 0.041319 0.068
7.74336e-08 7.30689e-08 0.360716 19.981796 -0.160611 0.006
7.74336e-08 7.30689e-08 0.361522 19.981796 0.243249 0.049
7.74336e-08 7.30689e-08 0.357897 19.986260 0.041319 0.035
Таких данных может быть 100 миллионов. Мне нужно отделить каждый столбец, разделить каждый столбец на блоки (скажем) 1000, затем выполнить усреднение каждого элемента в блоках, а затем снова объединить усредненные столбцы. Для приведенного ниже примера, если бы я усреднял только по 2 блокам по 3 элемента в каждом (вместо 100K по 1000 в каждом), то результат из столбца 6 будет:
0.0165 # =(0.027+0.006)/2 - 1st row from each size-3 block
0.042 # =(0.035+0.049)/2 - 2nd row
0.0515 # =(0.068+0.035)/2 - 3rd row
У меня уже есть программа для этого усреднения (это "Some_Complicated_Analysis"), и она отлично работает. Таким образом, все, что мне нужно, чтобы мой сценарий отделил столбцы, передал его в Some_Comp_Analysis, а затем снова объединил различные выходные данные в столбцы с paste
. Но файлы v. Большие, и я априори не знаю, сколько там столбцов. Если бы я знал, что будет только 2 столбца, то paste <(${cmd[1]}) <(${cmd[2]})
будет работать нормально.
РЕШЕНИЕ НАЙДЕНО
ОБНОВЛЕНИЕ: ответ найден - как показано в обновлении ответа Гленна Джекмана ниже. Команде paste
должен предшествовать eval
. Я не знаю точно, почему это необходимо, но без них расширение переменной ${cmd[]}
портит процесс подстановки <(...)
. Ответ выше также помещает двойные кавычки вокруг расширения массива "${cmd[*]}"
, однако они кажутся не столь важными - хотя без них некоторые другие расширения в cmd[]
могут потерпеть неудачу. Тем не менее, eval
необходимо.