Мне нужно прочитать файл и найти первое вхождение определенной строки, чтобы скопировать ее в другой файл

Проверьте состояние eth0из /sys/class/net/eth0/operstateи подождите, пока сетевой интерфейс не включится:

while ! [ "$(cat /sys/class/net/eth0/operstate)" = "up" ] 
do
    echo  "waiting for eth0 to be up"
    sleep 2
done

ip link add macvlan0 link eth0 type macvlan mode bridge
ip addr add 192.168.0.240/32 dev macvlan0
ip link set macvlan0 up
ip route add 192.168.0.240/28 dev macvlan0
2
08.05.2020, 17:17
2 ответа

Предполагая, что Кусалананда прав и каждая запись о сотруднике начинается со строки empid, следующая команда awkдолжна работать:

awk -F';' '$1=="empid" {delete a} !a[$1]++' input.txt > output.txt

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

Более подробное объяснение -:

  • $1=="empid" {delete a}будет удалять массив aкаждый раз, когда начинается новая запись
  • В
  • !a[$1]++используется сокращенная запись awk, согласно которой 1вне условного правила означает «печатать строку», тогда как 0означает «не печатать».
  • a[$1]++будет увеличивать «счетчик вхождений» для каждого значения имени атрибута, которое здесь принимается как «индекс массива».
  • Оценка !a[$1]++будет сначала проверять, равно ли текущее значение элемента массива нулю (, т. е. атрибут еще не встречался ), выполнять printдействие, если оно истинно (благодаря оператору отрицания )и последующему увеличению счетчика (это работает так же, как приращение префикса/постфикса в языках программирования в стиле C -). Таким образом, если атрибут еще не встречался, он печатается, но более поздние появления игнорируются.

Обратите внимание , что, хотя оператор delete aсоответствует синтаксису, принятому в стандарте POSIX в 2012 г., и приведенным выше работам над GNU awk, mawkи nawk, Стефан Шазеля указал, что для тех реализаций, которые не поддерживают этот синтаксис,

delete a

следует заменить на

split("",a)
4
28.04.2021, 23:15

Это та же основная идея, что и решение AdminBee , но немного менее элегантное (Я храню все значения в памяти без уважительной причины ), хотя и немного короче:

gawk -F';' '$1=="empid"{i=$2} ++a[i][$1]==1' file

Мы устанавливаем iна идентификатор сотрудника, если первое поле empid. Затем мы воспользуемся приятным небольшим трюком в awk :: когда выражение оценивается как истинное, awk напечатает строку. Итак, a[i][$1]— это элемент двумерного массива, первый ключ которого — текущий empid(, сохраненный как i), а второй ключ — 1-е поле текущей строки(a[i][$1]). Поскольку ++добавляет к этому единицу, выражение ++a[i][$1]==1будет истинным только в первый раз, когда каждое поле видно для конкретного empid. Поскольку мы печатаем только в том случае, если это правда, команда будет печатать первое вхождение для каждого идентификатора.

Обратите внимание, что для этого требуется GNU awk.

1
28.04.2021, 23:15

Теги

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