Як я можу "об'єднати" візерунки в один рядок?


10

Я роблю grep і sed, і я отримую 2 рядки файлу, який мене цікавить. Як я можу отримати ці рядки в одному рядку, що закінчується новим символом рядка?
Тепер я отримую:

pattern1  
pattern2  

Я хотів би отримати pattern1 pattern2 \n


1
Чи можете ви поділитися більше зразків даних?
slm

Використання printf %s\\n pattern1 pattern2 | sed '$!N;s/\n/ /'
Валентин Байрамі

Вставити - це інструмент для завдання, якщо ви збираєтесь об'єднати кілька рядків виводу в один.
slm

якийсь конкретний інструмент? Як ви плануєте це зробити?
Брайам

Відповіді:


7

paste:

{...pipeline...} | paste -d " " - -

Це говорить: "прочитайте рядок зі stdin (перший -), прочитайте інший рядок зі stdin (другий -), а потім з'єднайте їх із пробілом"


баш-специфічна техніка:

$ x=$(grep -o pattern. test.txt)
$ echo "$x"
pattern1
pattern2
$ mapfile -t <<< "$x"
$ echo "${MAPFILE[*]}"
pattern1 pattern2

ref: http://www.gnu.org/software/bash/manual/bashref.html#index-mapfile


Що таке - -? Чи така команда?
Джим

@Jim - так, це правильно. Вони розповідають, pasteяк ви хочете, щоб вона обробляла дані. 2 за раз. Додайте більше, щоб зробити 3 одночасно. seq 10 | paste -d " " - - .
slm

6

Я покладу три версії різних методів підряд

AWK

printf %s\\n pattern1 pattern2 | awk -vRS="\n" -vORS=" " '1; END {print RS}'

СЕД

printf %s\\n pattern1 pattern2 | sed '$!N;s/\n/ /'

TR

printf %s\\n pattern1 pattern2 | tr '\n' ' '; echo

І ще багато.


trРішення проковтне закінчення нового рядка, так що ви можете додати ; echoдо цього один
Glenn Джекман

@glennjackman ах прав! Дякую за підказку. Ви можете вільно змінити відповідь. Я пропустив цей шматочок!
Валентин Байрамі

2

ви можете зробити це за допомогою сценарію оболонки або в командному рядку, просто покладіть вихідну команду в змінну, а потім echo:

# x=$(grep -e "pattern1\|pattern2" test)
# printf '%s\n' "$x"
pattern1 pattern2

без котирування, змінна також підлягає розширенню імен файлів, тому якщо у вас є якісь глобальні символи (наприклад, *або ?), результати можуть змінюватися.
glenn jackman

@glennjackman, дякую за згадку про це, як це можна виправити?
Нідаль

@Networker, не використовуючи задні посилання, а $()замість цього .. та використовуючи printfprintf '%s\n' "$x"
Валентин Байрамі

Я би сподівався, що printf '%s\n' "$x"НЕ видалить "внутрішній" новий рядок.
Гленн Джекман

2

За допомогою цього sedви можете зробити:

<your previous commands> | sed '{N; s/\n/ /}'
  • N;говорить sedдодати наступний рядок у простір шаблону, тому зараз sedпрацює з обома рядками.
  • s/\n/ / замінює символ нового рядка пробілом, "об'єднуючи" два рядки разом.

2

Простий спосіб вивести трубу на xargs:

$ echo -e 'a\nb' | xargs
a b

Це працює лише з невеликим виходом, оскільки воно обмежене максимальним числом символів у командному рядку. Найбільше значення залежить від системи, ви можете отримати це значення, використовуючи getconf ARG_MAX.


1
( set -f; IFS='
'; printf '%s %s\n' $(grepcmd <input)
) >output

IFS буде рада з'їсти його, якщо захочете.


-1

загорніть свій зад / греп у задній план

коли ваша початкова команда:

grep -i 'foo' mylog.log | sed 's/bar/baz/gi'

Вашою новою командою було б:

`grep -i 'foo' mylog.log | sed 's/bar/baz/gi'`

Не розміщено пробіли між рядками, але ви завжди можете застосувати іншу сед-трубу:

 | sed 's/$/ /'

1
Ні, ні. Це виконає вихід команди sed.
glenn jackman
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.