Попытка добавить новую строку в команду вставки

Попытка добавить новую строку в команду вставки

Вот слабая попытка команды вставки, пытающейся включить новую строку:

    paste -d -s tmp1 tmp2 \n tmp3 \n tmp4 tmp5 tmp6 > tmp7

По сути у меня есть несколько строк в каждом tmp и я хочу, чтобы вывод был таким:

First(tmp1) Last(tmp2)
Address(tmp3)
City(tmp4) State(tmp5) Zip(tmp6)

Я ошибаюсь, используя новую строку в команде вставки?

Вот мой готовый продукт: СПАСИБО ЗА ПОМОЩЬ!

    cp phbook phbookh2p5

    sed 's/\t/,/g' phbookh2p5 > tmp
    sort -k2 -t ',' -d tmp > tmp0
    cut -d',' -f1,2 tmp0 > tmp1
    cut -d',' -f3 tmp0 > tmp2
    cut -d',' -f4,5,6 tmp0 > tmp3
    echo "" > tmp4

    paste -d '\n' tmp1 tmp2 tmp3 tmp4 > tmp7

    sed 's/\t/ /g' tmp7 > phbookh2p5

    cat phbookh2p5

    rm tmp*; rm phbookh2p5

решение1

Попробуйте это решение с двумя дополнительными временными файлами:

paste tmp1 tmp2 > tmp12
paste tmp4 tmp5 tmp6 > tmp456
paste -d "\n" tmp12 tmp3 tmp456 > tmp7

Это решение было основано на предположении, что -dопция выбирает разделительглобальнодля всех входных файлов, поэтому он может быть пустымилиновая строка. В некотором смысле это верно, поскольку последующие появления -dперезаписывают предыдущие. Однако, как указал @DigitalTrauma, мы можем предоставить более одного разделителя, которые будут использоваться последовательно. Поэтому решение @DigitalTrauma более элегантно, чем мое, поскольку оно полностью избегает дополнительных временных файлов.

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

решение2

Я думаю, что эта часть pasteстраницы руководства — то, что вам нужно:

   -d, --delimiters=LIST
          reuse characters from LIST instead of TABs

Итак, эта однострочник должен подойти для вашего случая:

paste -d" \n\n  " tmp1 tmp2 tmp3 tmp4 tmp5 tmp6 > tmp7

Работает, как и ожидалось, с образцами данных @DopeGhoti:

$ grep . tmp*
tmp1:Bill
tmp1:Bob
tmp2:Kerman
tmp2:Germin
tmp3:123 Main St.
tmp3:321 Sesame St.
tmp4:Kerbopalis
tmp4:Kerbington
tmp5:Kerbskatchewan
tmp5:Kermont
tmp6:12345
tmp6:31416
$ paste -d" \n\n  " tmp1 tmp2 tmp3 tmp4 tmp5 tmp6
Bill Kerman
123 Main St.
Kerbopalis Kerbskatchewan 12345
Bob Germin
321 Sesame St.
Kerbington Kermont 31416
$ 

Я успешно протестировал это с pasteGNU Coreutils 5.97 и 8.21 и BSD (OS X). Не уверен, какие еще версии paste существуют в свободном доступе.

решение3

Эта команда должна сработать.

 paste -s tmp1 tmp2 -d '\n' tmp3 -d '\n' tmp4 tmp5 tmp6 > tmp7

решение4

sort -dk2,2 phpbook |
sed "s/\t/\n/3;s//\n/2;s// /g"

Насколько я понимаю, у вас есть файл, phpbookкоторый состоит из строк записей телефонной книги, которые выглядят примерно так:

{first}\t{last}\t{address}\t{city}\t{state}\t{zip}

Вы хотите отсортировать их по {last}, добавить новые строки после {last}и {address}для каждой записи, перевести \tabs в <spaces>, а затем вывести результаты в stdout. Если это не так, то я не могу понять, что еще должна делать ваша команда - но я иногда могу быть довольно тупым.

Обратите внимание, что по умолчанию sortразделители используются по символам:<TAB>

sed 's/\t/,/g' | sort ... -t ,

...вероятно, этого не стоит делать.

Думаю, есть еще кое-что, и я полагаю, что вполне вероятно, что ваши разделители смешаны, а инициал sedпредназначен для их нормализации. Это имеет смысл. Может быть, как:

1,2\t3\t4,5,6

...или что-то в этом роде. В таком случае необходим какой-то первоначальный перевод. Так что, может быть...

tr , \\t <phbook | sort ... | sed ...

будет работать немного лучше. Также...

sort ... -k 2

...мощьбыть проблематичным в крайних случаях, потому что когда вы его используете, вы sortнетольковторое поле, а скорее от второго поля до конца строки. В общем, когда люди делают это, они действительно хотят, -k2,2что ограничивает данные, sortкоторые рассматриваютсятольковторое поле.

Также может быть целесообразно добавить вторичный ключ, например:

...sort -dk2,2 -k1,1

...которые быsort в первую очередьпо фамилиям ивторичнопо именам. Таким образомЗед Смитбудет следоватьАльфа Смиткаждый раз.

В любом случае, если я прав, конвейер sort | sedвыше должен сделать все это. Я предполагаю, что вы sedпонимаете, какие \escapes я использовал, но если нет, то вы можете попробовать заменить цитируемый sedскрипт на:

s/<literal TAB>/\
/3;s//\
/2;s// /g

Связанный контент