Разделите "дублирующиеся строки" пустой строкой

Это работает как в bash (начиная с версии 4.3), так и в ksh93 . Чтобы «придать басу» его, замените весь набор на локальный в функциях, а набор в глобальной области видимости на declare (тогда как сохраняю все варианты!). Честно говоря, я не знаю, почему в Bash так много разных имен для вещей, которые являются всего лишь вариациями typeset .

function stack_push
{
    typeset -n _stack="$1"
    typeset element="$2"

    _stack+=("$element")
}

function stack_pop
{
    typeset -n _stack="$1"
    typeset -n _retvar="$2"

    _retvar="${_stack[-1]}"

    unset _stack[-1]
}

typeset -a stack=()

stack_push stack "hello"
stack_push stack "world"

stack_pop stack value
printf '%s ' "$value"

stack_pop stack value
printf '%s\n' "$value"

Используя nameref в функции, вы избегаете eval (мне никогда не приходилось использовать eval в любом скрипте!). Предоставляя функции stack_pop место для хранения всплывающего значения, вы избегаете подоболочки.Избегая подоболочки, функция stack_pop может изменять значение переменной stack во внешней области видимости.

Подчеркивания в локальных переменных в функции предназначены для того, чтобы избежать ссылки на имя, имя которой совпадает с именем переменной, на которую она ссылается (Bash это не нравится, ksh не возражает, см. этот вопрос ).

В ksh вы можете написать функцию stack_pop , например

function stack_pop
{
    typeset -n _stack="$1"

    printf '%s' "${_stack[-1]}"

    unset _stack[-1]
}

, а затем вызвать ее с помощью

printf '%s %s\n' "${ stack_pop stack }" "${ stack_pop stack }"

( $ {...} - это То же, что $ (...) , но не создает подоболочку)

Но я не большой поклонник этого. IMHO, stack_pop не должен отправлять данные на стандартный вывод, и мне не нужно вызывать его с помощью $ {...} для получения данных. Я мог бы быть более в порядке с моим исходным stack_pop , а затем добавить stack_pop_print , который делает то же самое, если необходимо.

Для Bash вы можете использовать stack_pop в начале моего сообщения, а затем иметь stack_top_print , который просто выводит верхний элемент стека в стандартный вывод, не удаляя он (чего не может, потому что он, скорее всего, будет работать в подоболочке $ (...) ).

1
09.10.2016, 18:52
3 ответа

Вот основная команда, которую вы можете адаптировать к своим индивидуальным потребностям.

awk '{print $0 > $1}' inputfile

РЕДАКТИРОВАТЬ: Извините, я только что понял, что неправильно прочитал ваш вопрос, это неправильный ответ, хотя вы можете достаточно легко «соединить» файлы с пустыми строками

Вот возможное решение

for file in $(awk '{print $1; print $0 > $1}' data.txt | sort | uniq)
do
  cat $file
  echo
  rm $file
done > output.txt

Решение, просто используя awk, если файл предварительно отсортирован:

awk '{a=$1; if (b != "" && a != b) {printf "\n";}; print $0; b = a}' inputfile

Переработано после комментариев don_crissti (спасибо!)

awk '{if (a != "" && a != $1) {printf "\n";}; print $0; a = $1}' inputfile
1
27.01.2020, 23:25

Решение sed может быть

sed '
    /^\n/!{                             #if line do not starts from \newline 
        N                               #attach next line
        /^\(\w\+\b\).*\n\1/! s/\n/\n\n/ #if 1st word not a same insert \newline
    }
    P                                   #print 1st line (before \newline)
    D                                   #remove 1st line, return to start
    '
1
27.01.2020, 23:25

другое решение awk предполагает сортировку ввода, как показано в примере ввода

$ cat ip.txt 
fruit  apple word
fruit  lemon
fruit  orange other word
meat  ham word
vegetable  salad other
vegetable  lettuce more

Примечание. Порядок проверки условий имеет значение.

$ awk '!seen[$1]++ && NR>1{printf "\n"} 1' ip.txt 
fruit  apple word
fruit  lemon
fruit  orange other word

meat  ham word

vegetable  salad other
vegetable  lettuce more


Аналогичное решение в perl

$ perl -ane 'print "\n" if !$seen{$F[0]}++ && $. > 1; print' ip.txt 
fruit  apple word
fruit  lemon
fruit  orange other word

meat  ham word

vegetable  salad other
vegetable  lettuce more
1
27.01.2020, 23:25

Теги

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