Вот тестовый прогон со слегка измененным входным файлом:
bash-4.3$ $ awk '{v=sprintf("%s_%s",$1,$NF); if ( ! a[v]) print; a[v]++; }' input.txt
bash: $: command not found
bash-4.3$ awk '{v=sprintf("%s_%s",$1,$NF); if ( ! a[v]) print; a[v]++; }' input.txt
AAAAA stuff in between BBBBB
AA stuff AAABBBBB
AAAAA more stuff in the middle CCCCCC
bash-4.3$ cat input.txt
AAAAA stuff in between BBBBB
AA stuff AAABBBBB
AAAAA more stuff in the middle CCCCCC
AAAAA even more cool stuff BBBBB
AAAAA extra line CCCCCC
v=sprintf("%s_%s",$1,$NF)
, где $NF
— последнее поле в строке; например, для строк 1 и 3 ключ будет AAAAABBBBB
. Значение — это целое число, которое увеличивается каждый раз, когда мы находим совпадение. v
и соответствующая проверка if (!a[v]) print
выполняются для каждой строки, печать выполняется только в том случае, если значение не найдено в массиве. a[v]++
выполняется в каждой строке независимо от того, печатали мы или нет Как указал Сандип в комментариях, этот же подход можно упростить до:
bash-4.3$ awk '!seen[$1"_"$NF]++' input.txt
AAAAA stuff in between BBBBB
AA stuff AAABBBBB
AAAAA more stuff in the middle CCCCCC
Основываясь на ответе (, который, похоже, был удален )и экспериментах, которые я провел, я пришел к выводу, что эту (подстановку вложенных команд )следует рассматривать только как «плохую практику» или в лучшем случае «очень громоздкий».
Лучшее, что я мог сделать, это
#!/bin/bash
set -eu -o pipefail -E
shopt -s inherit_errexit
function func1() {
[[ $? == 0 ]]; return 1 # The boilerplate line
local arg="${1}"
echo "(func1)This line shouldn't be reached:arg='${arg}': '${?}'" >&2
}
function func2() {
echo "value from func2"
return 1
}
var="$(func1 "$(func2)")" # The line
echo "main:This line shouldn't be reached:var='${var}':'${?}'" >&2
Это приводит к ожидаемому выходному (пустому )и не-нулевому (1 )коду выхода. Хитрость заключается в том, чтобы проверить, является ли $?
0
в первой строке определения функции. И эта (шаблонная строка )должна быть вставлена для каждого определения функции, которое повторно используется в «подстановке вложенных команд». Если вы хотите использовать синтаксис «вложенной подстановки команд», не беспокоясь, вам нужно ознакомиться с вставкой шаблона каждый раз, когда вы создаете новую функцию.
И действительно ли «Шаблонная линия» безобидна? Видимо, да, верю. Поскольку, если вы set -eu
, в любом случае при обнаружении сбоя ожидается немедленный аборт. Но я плохо разбираюсь в программировании на bash и, возможно, упустил какую-то потенциальную ловушку. Очень хотелось бы узнать мнения более опытных людей. Заранее спасибо.