Думайте, что это не верно. Имел ту же проблему. Alsamixer всегда передискретизирует все потоки к значению по умолчанию 44,1 кГц. Я не могу вообразить другой путь, как смешать потоки с другой частотой дискретизации, чем передискретизируют их к одному общему. Надлежащий файл для изменения это - ~/.asoundrc
http://www.alsa-project.org/main/index.php/Asoundrc
Можно проверить результат здесь: кошка/proc/asound/card0/pcm0p/sub0/hw_params (или card1, если у Вас есть 2 карты),
Так как вы не просили 100% awk
решение,
Я предложу гибрид, который (а), возможно, будет легче понять,
и (b) не напрягает границы памяти awk
:
awk '
$1 == 2 { secondpart = 1 }
{ if (!secondpart) {
print > "top"
} else {
print $1, $2 > "left"
print $5, $6, $7, $8, $9 > "right"
}
}' a
(cat top; paste -d" " left b c right) > new_a
rm top left right
Или мы можем удалить один из временных файлов и сократить скрипт одной командой:
(awk '
$1 == 2 { secondpart = 1 }
{ if (!secondpart) {
print
} else {
print $1, $2 > "left"
print $5, $6, $7, $8, $9 > "right"
}
}' a; paste -d" " left b c right) > new_a
rm left right
Это поместит несколько лишних пробелов в конце строк вывода,
и она потеряет данные из файла a
, если какая-либо строка содержит более девяти полей (столбцов).
Если это проблемы, то их можно довольно легко исправить.
Неуклюжий способ:
awk '{if(FNR==NR){f2[FNR+1]=$1;}
else{
if(FNR==1){k++;}
if(k==1){f3[FNR+1]=$1}
else{if($1~/^[0-9]+/ && $1>1){$3=f2[$1];$4=f3[$1];}
print}
}}' file2 file3 file1
Это то же самое, что написано в виде прокомментированного сценария для ясности:
#!/usr/local/bin/gawk -f
{
## NR is the current line number, irrespective of
## which input file is being read. FNR is the line
## number of the current file. It is reset to 1 each
## time a new file is opened. Therefore, FNR will be
## equal to NR only while the 1st file is being read.
if(FNR==NR){
## If this is the 1st file, save its 1st field
## in the array f2. The key of the array is the
## line number of the current file plus one. This is
## because you want to start modifying from row '2' onwards.
## Therefore, presumably, you want the 1st row of file2 to
## be the value for row '2' of your data file..
f2[FNR+1]=$1;
}
## If this is not the 1st file
else{
## If this is the 1st line of the current file
if(FNR==1){
## Increase the value of the variable k by 1.
k++;
}
## If k is currently 1, this means that the above has only
## been run once so we are currently reading the 1nd file.
if(k==1){
## Save the 1st field of this file (file3 in your example)
## in the array f3. The key of the array is the
## line number of the current file plus one.
f3[FNR+1]=$1
}
## If k is not 1, we are reading the 3rd file. In this case,
## your actual data.
else{
## If the 1st field is a number and is greater than 1.
## In other words, if this is one of the lines you want
## to change.
if($1~/^[0-9]+/ && $1>1){
## Set the 3rd field to be the value saved in the array
## f2 for the value of $1.
$3=f2[$1];
## Set the 4th field to be the value saved in the array
## f3 for the value of $1.
$4=f3[$1];
}
## Print the current line. Since this is outside the
## previous if block, it will print all lines irrespective
## of whether they've been modified.
print;
}
}
}
A Perl way:
perl -lane 'BEGIN{
open(A,"file2"); while(<A>){chomp; $f2{$.+1}=$_;}
open(B,"file3"); while(<B>){chomp; $f3{$.+1}=$_;}}
if($F[0]=~/^\d+$/ && $F[0]>1){$F[2]=$f2{$F[0]}; $F[3]=$f3{$F[0]}}
print "@F"' file1
-lane
: l
автоматически удалит из конца каждой входной строки (так же, как chomp
) и добавит новую строку к каждому оператору распечатки
. В случае a
каждая входная строка будет автоматически разделена пробелом на массив @F
, в результате чего perl будет выполняться как awk. n
означает "запуск скрипта, предоставленного -e
в каждой строке входного файла". BEGIN{...}
: он выполняется до чтения входного файла. В этом случае я открываю каждый из дополнительных файлов и сохраняю их содержимое в хэшах %f2
и %f3
. В основном это то же самое, что и массивы awk
, которые я использовал выше. if($F[0]=~/^\d+$/ && $F[0]>1){...}
: опять же, это та же логика, что и в скрипте awk. Она заменит поля на соответствующие записи каждого файла. распечатать "@F"
: это распечатает все поля. вот что я придумал.
ваши данные находятся в a.txt, третий столбец - в b.txt (я поставил название дня недели для ясности, это также будет работать с номером).
mybox $ cat b.txt
day monday tuesday wednesday thursday friday saturday
mybox $ cat a.txt
1 4324 3673 6.2e+11 7687 67576
2 3565 8768 8760 5780 8778
3 7656 8793 -3e+11 7099 79909
4 8768 8965 8769 9879 0970
5 5878 9879 7.970e-1 9070 0709799
100000 3655 6868 97879 96879 69899
mybox $ cat ul.awk
FILENAME == "b.txt" { for (i=2;i<=NF;i++) value_one[i-1]=$i ; next ; }
{printf "%s %s %s %s %s %s\n",$1,$2,value_one[FNR],$4,$5,$6}
mybox $ awk -f ul.awk b.txt a.txt
1 4324 monday 6.2e+11 7687 67576
2 3565 tuesday 8760 5780 8778
3 7656 wednesday -3e+11 7099 79909
4 8768 thursday 8769 9879 0970
5 5878 friday 7.970e-1 9070 0709799
100000 3655 saturday 97879 96879 69899
однако я не уверен, что awk может обрабатывать 99999 столбцов .
Это то, что вы ищете? (кроме слияния только одного файла)
редактировать 1 b.txt одиночный столбец (кстати, это устраняет любые проблемы с awk).
mybox $ cat a.txt
1 4324 3673 6.2e+11 7687 67576
2 3565 8768 8760 5780 8778
3 7656 8793 -3e+11 7099 79909
4 8768 8965 8769 9879 0970
5 5878 9879 7.970e-1 9070 0709799
100000 3655 6868 97879 96879 69899
mybox $ cat b.txt
monday
tuesday
wednesday
thursday
friday
saturday
содержание ul.awk
FILENAME == "b.txt" { value[FNR]=$i ; }
FILENAME != "b.txt" { printf "%s %s %s %s %s %s\n",$1,$2,value[FNR],$4,$5,$6}
mybox $ awk -f ul.awk b.txt a.txt
1 4324 monday 6.2e+11 7687 67576
2 3565 tuesday 8760 5780 8778
3 7656 wednesday -3e+11 7099 79909
4 8768 thursday 8769 9879 0970
5 5878 friday 7.970e-1 9070 0709799
100000 3655 saturday 97879 96879 69899
приближается ли это?
{ { paste -d\ /dev/fd/[345] |
sed 's/ \( [^ ]*\)\(.*\)/\2\1/'
} 3<<FILE1 4<<FILE2 5<<FILE3
$(<file1 sed '1,/^1/w /dev/fd/2
/^2/,$!d;s/ [^ ]*//4;s// /3')
FILE1
$(<file2 tr -s \\n)
FILE2
$(<file3 tr -s \\n)
FILE3
} 2>&1
В приведенной выше последовательности команд я изрядно жонглировал входом / выходом. Делается это довольно просто. файл [23]
на самом деле идентичны - они оба являются копией ваших 99 999 строк строк 3/4. Остается file1
- это , по сути, точный файл в вашем примере выше, но строка 5 дублируется в 6 и 7, чтобы соответствовать file [23]
.
По сути, каждый файл просто получает свой собственный файловый дескриптор и свою подготовительную работу. файл [23]
почти не требует подготовки - tr
просто сжимает все повторяющиеся \ n
символы электронной строки в один - так что пустые строки исчезают.
file1
получает немного больше. Сначала все строки до и включая первую строку, начинающуюся с 1
, записываются в stderr
. Затем они удаляются из вывода - поэтому они попадают только в > & 2
. Далее sed
выбирает столбцы 3/4 и заменяет их одним пробелом - это означает, что там, где они были, теперь есть два последовательных символа пробела.
paste
собирает все файловые дескрипторы и склеивает их вместе, разделенные пробелами. Затем sed
пытается поменять местами первую последовательность непробельных символов, следующих сразу за двумя пробелами, на все, что после них.
Наконец, файловые дескрипторы для stderr
и stdout
объединены в stdout
. Результат выглядит так:
$data This is the experimental data
good data
This is good file
datafile
1 4324 3673 6.2e+11 7687 67576
2 3565 8768 12414 12414 8778
3 7656 8793 12421 12421 79909
4 8768 8965 36347 36347 0970
5 5878 9879 3.4e+3 3.4e+3 0709799
6 5878 9879 -3.5e22 -3.5e22 0709799
7 5878 9879 987983 987983 0709799
. . .
. . .
. . .
100000 3655 6868 87698 87698 69899
$.endfile
Другой awk путь без массивов, это - определенная путаница, таким образом, я попытаюсь убрать его позже
awk 'function get(file,L) {x=1
while ( (getline < file) > 0) {if(NR==x)y=$0;x++}
close(file)
return y
}
ARGV[1]==FILENAME{d=$0;a=get(ARGV[2],$0);b=get(ARGV[3],$0);$0=d;$2=a;$3=b;print
}' file file1 file2