Вот слабая попытка команды вставки, пытающейся включить новую строку:
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
$
Я успешно протестировал это с paste
GNU 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}
для каждой записи, перевести \t
abs в <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
понимаете, какие \e
scapes я использовал, но если нет, то вы можете попробовать заменить цитируемый sed
скрипт на:
s/<literal TAB>/\
/3;s//\
/2;s// /g