Длина массива сценария оболочки Bash прочь одной

Вы были почти там. Просто измените индекс массива на $1 – который является общим элементом обоих файлов:

awk 'NR==FNR {a[$1]=$2;next} $1 in a {print $2, a[$1]}' file2 file1

И никакая идея, почему Вы помещаете $1$ 2 в массив, поскольку Вам, кажется, нужны только 2$.

Обновление согласно редактированию вопроса.

Вы ясно помещаете то “соответствие f2 $1 с f1 $3” (Я желаю, каждый вопрос быть настолько ясным) поэтому просто пишут это в коде соответственно:

              f2 $1                             f1 $3
                |                                 |
awk 'NR==FNR {a[$1]=$2;next} $3 in a {print $0, a[$3]}' f2 f1
4
05.03.2015, 20:45
1 ответ

Чтобы ответить на ваш список вопросов по номеру:

  1. Именованные трубы, а.k.a. fifos по существу эквивалентны неназванным трубам, генерируемым оболочкой. Большая разница в том, что синхронизация между двумя концами интуитивно понятна с версией оболочки, в то время как именованные трубы, как вы, кажется, используете их, требуют немного знаний о том, что оболочка делает для вас.

  2. Да, оба конца ждут друг друга. Назначение fifos, как и оболочечных труб, состоит в передаче выхода из одного процесса на вход другого. Они не являются временными файлами. Я подозреваю, что именно здесь вы запутались. В случае команды shell, такой как cat somefile.txt | less , обе команды выполняются одновременно как форсированные процессы, причем труба служит для синхронизации этих двух процессов. Это может быть изменено, если память служит, в C, но не так легко с помощью команд оболочки.

  3. Процессы могут принимать сигналы, когда другой конец трубы получает соединение, но чаще всего, как было отмечено выше, цель состоит в поддержании синхронизации двух процессов. Модуль записи отправляет что-либо, и он знает, что это может продолжаться после завершения операции записи.

  4. bash и tcsh не дадут втянуть «в забвение». Команда даже не выполняется.

  5. tail -f должен считывать весь поток, пока он не получит EOF, в данном случае на stdin , прежде чем он сможет отобразить что-либо. В вашем эксперименте конец так и не появился. cat , с другой стороны, может начать работу над своим входом немедленно.

  6. Поскольку процесс написания не отправляет новые строки, читатель просто читает, пока ему не сказали, что этого «достаточно». В первом случае это, вероятно, потому, что буфер fifo заполнен, и, следовательно, проник к читателю. Последующий выход, вероятно, аналогичен и, вероятно, будет изменяться в зависимости от времени системы.

Позвольте мне обратиться к еще одной путанице. Оболочка обрабатывает перенаправление перед выполнением команды . Это означает, что вы не увидите cat в списке процессов, потому что bash находится в ожидании другого конца fifo для подключения перед запуском cat или какого-либо устройства записи. Аналогично, он не будет выполнять команду чтения, пока не подключится устройство записи.

Я думаю, что самое большое недоразумение у вас здесь заключается в том, что именованные трубы не временные файлы. Как и безымянные трубы. Несмотря на то, что существуют способы сделать связь асинхронной, будет лучше создать фактические временные файлы в /tmp , если не требуется одновременное выполнение обоих процессов.

-121--70736-

Я думаю, что было бы ошибкой называть так много sed s, где только один будет делать. претензия sed на известность заключается в его способности эффективно закольцовывать входные данные и модифицировать их в различные выходные данные,но он также может обрабатывать несколько выходов. Вот, например, портативный POSIX (и гораздо более эффективный) перезапись вашего для цикла:

echo "Solve[x^2+5^a==$((a=0)),x]>>a.out" >/tmp/i.m    ###create file + init $a
until [ "$((a+=1))" -gt 10 ]                          ###iterate + test
do    printf "h;s/a/$a/gpw /tmp/$a.m\ng;"             ###push new sed command
done| sed -nf - /tmp/i.m                              ###read + apply commands
head /tmp/[0-9].m /tmp/10.m                           ###print results

sed может прочитать свой скрипт из stdin и применить его к именованному файлу - вот что делает приведенная выше инструкция sed -nf -/tmp/i.m . Он также может одновременно p печатать свои выходные данные в stdout и w переводить свои выходные данные в один или несколько именованных файлов. По мере работы контура оболочки он печатает строки на sed , которые, по завершении, составляют:

h;s/a/1/gpw /tmp/1.m
g;h;s/a/2/gpw /tmp/2.m
g;h;s/a/3/gpw /tmp/3.m
g;h;s/a/4/gpw /tmp/4.m
g;h;s/a/5/gpw /tmp/5.m
g;h;s/a/6/gpw /tmp/6.m
g;h;s/a/7/gpw /tmp/7.m
g;h;s/a/8/gpw /tmp/8.m
g;h;s/a/9/gpw /tmp/9.m
g;h;s/a/10/gpw /tmp/10.m
g

, что говорит sed ...

  1. Перезаписать старый буфер h копией буфера редактирования.
  2. g лобово s/// заполняет каждое вхождение буквы a в ее буфере редактирования любым текущим значением переменной оболочки $ a .
  3. Одновременно p печатает результаты s/// до stdout и w записывает результаты в файл с именем /tmp/$ a.m , где $ a является итерабельным.
  4. И, наконец, g выберите буфер хранения путем перезаписи буфера редактирования.

sed будет применять эту последовательность для каждой строки в именованном входном файле. При первом вызове он усекает каждый из своих именованных файлов w обрядов, но затем добавляет каждое действие w обрядов к каждому выходному файлу в последовательность. Поскольку у меня есть только одна строка в i.m , однако, sed печатает:

Solve[x^2+5^1==0,x]>>1.out
Solve[x^2+5^2==0,x]>>2.out
Solve[x^2+5^3==0,x]>>3.out
Solve[x^2+5^4==0,x]>>4.out
Solve[x^2+5^5==0,x]>>5.out
Solve[x^2+5^6==0,x]>>6.out
Solve[x^2+5^7==0,x]>>7.out
Solve[x^2+5^8==0,x]>>8.out
Solve[x^2+5^9==0,x]>>9.out
Solve[x^2+5^10==0,x]>>10.out

и head , считывая из каждого из вновь созданных десяти файлов в /tmp , печатает:

==> /tmp/1.m <==
Solve[x^2+5^1==0,x]>>1.out

==> /tmp/2.m <==
Solve[x^2+5^2==0,x]>>2.out

==> /tmp/3.m <==
Solve[x^2+5^3==0,x]>>3.out

==> /tmp/4.m <==
Solve[x^2+5^4==0,x]>>4.out

==> /tmp/5.m <==
Solve[x^2+5^5==0,x]>>5.out

==> /tmp/6.m <==
Solve[x^2+5^6==0,x]>>6.out

==> /tmp/7.m <==
Solve[x^2+5^7==0,x]>>7.out

==> /tmp/8.m <==
Solve[x^2+5^8==0,x]>>8.out

==> /tmp/9.m <==
Solve[x^2+5^9==0,x]>>9.out

==> /tmp/10.m <==
Solve[x^2+5^10==0,x]>>10.out
-121--139702-

Последнее чтение, которое не может найти больше данных, назначит пустой ряд Для проверки используйте printf «»% s «»\n« »$ {students [@]}« ».

8
27.01.2020, 20:49

Теги

Похожие вопросы