Как я могу «объединить» шаблоны в одну строку?

10

Я делаю grep и sed, и я получаю 2 строки файла, который меня интересует. Как я могу получить эти строки в одной строке, заканчивающейся символом новой строки?
Теперь я получаю:

pattern1  
pattern2  

Я хотел бы получить pattern1 pattern2 \n

Джим
источник
1
Можете ли вы поделиться более примерами данных?
СЛМ
Использование printf %s\\n pattern1 pattern2 | sed '$!N;s/\n/ /'
Валентин Байрами
Вставить - это инструмент для работы, если вы собираетесь объединить несколько строк вывода в одну.
СЛМ
какой-то конкретный инструмент? Как вы планируете это сделать?
Брайам

Ответы:

7

paste:

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

Это говорит: «прочитать строку из stdin (первый -), прочитать другую строку из stdin (второй -), а затем соединить их пробелом»


специфичная для bash техника:

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

ссылка: http://www.gnu.org/software/bash/manual/bashref.html#index-mapfile

Гленн Джекман
источник
Что такое - -? Команда такая?
Джим
@ Джим - да, это правильно. Они рассказывают, pasteкак вы хотите, чтобы он обрабатывал ввод. 2 за один раз. Добавьте больше, чтобы сделать 3 одновременно. seq 10 | paste -d " " - - ,
SLM
6

Я поставлю три версии разных методов подряд

AWK

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

SED

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
Нидал
источник
без кавычек переменная также подвергается расширению имени файла, поэтому, если в результате появятся какие-либо символы-глобусы (например, *или ?), значения могут измениться.
Гленн Джекман
@glennjackman, спасибо, что упомянули это, как мы можем это исправить?
Нидаль
@Networker не используя обратные пометки, а $()вместо этого ... и используя printfprintf '%s\n' "$x"
Valentin Bajrami
Я ожидаю, что 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.

cuonglm
источник
1
( set -f; IFS='
'; printf '%s %s\n' $(grepcmd <input)
) >output

IFS будет рад съесть его, если вы хотите.

mikeserv
источник
-1

оберните ваш сед / grep в спину

когда ваша оригинальная команда была:

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

ваша новая команда будет:

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

Не получает пробелов между строками, но вы всегда можете использовать другую трубу sed:

 | sed 's/$/ /'
TheRuss
источник
1
Нет Это выполнит вывод команды sed.
Гленн Джекман