複数行の出力を1行に連結する方法は?


158

コマンドを実行すると、cat file | grep pattern何行もの出力が得られます。すべての行を1行に連結して、各行"\n""\" "(末尾に"スペースが続く)で効果的に置き換えるにはどうすればよいですか?

cat file | grep pattern | xargs sed s/\n/ /g 私のために働いていません。


ちなみに、(1)sedBashがスクリプトを混乱させないように、スクリプトを単一引用符で囲む必要があります(2つの引数を使用したsed s/\n/ /g呼び出しsed、つまりs/n//g)。(2)あなたはの出力が欲しいので、cat file | grep patternする入力sedない、引数sed、あなたは排除する必要がありますxargs。(3)2番目の引数としてファイル名を取ることができるため、catここでは必要ありませんgrep。だから、試してみるべきだったgrep pattern file | sed 's/\n/ /g'。(この場合、上記のリンクに示されている理由により、機能しませんでしたが、今、あなたは将来のために知っています。)
ruakh


68票(14万ビュー)の質問は、1票(12万ビュー)しかない投稿と重複していますか?これは正しくありません。
kenorb 2018年

回答:


231

tr '\n' ' 'すべての改行文字をスペースに変換するために使用します:

$ grep pattern file | tr '\n' ' '

注:grepファイルを読み取り、ファイルをcat連結します。やめろcat file | grep

編集:

tr単一文字の翻訳のみを処理できます。次のawkようにして、出力レコードセパレータを変更できます。

$ grep pattern file | awk '{print}' ORS='" '

これは変換します:

one
two 
three

に:

one" two" three" 

3
このアプローチでは、最後に不要なスペースができてしまいます。
ソリン2016年

1
echo ""プロンプトテキストの前に新しい行を追加するには、最後に追加する必要があります。
nexayq 2016

1
これはうまくいきますが、最後のエントリにセパレータを表示したくありません。たとえば、の"ように表示されますが、のように表示しone" two" three"たいですone" two" three。最後の3つには括弧がないことに注意してください。何か案は?
OINK

2
@oink結果をパイプsed '$s/..$//'して、最終行の最後の2文字を削除できます。
Chris Seymour

3
改行を何も置換しない--delete場合は、デフォルトで2つの引数が想定されるため、このオプションを使用する必要があります。例えばtr --delete '\n'
Elijah Lynn

69

出力をパイピングするxargsと、出力の各行がスペースを含む1行に連結されます。

grep pattern file | xargs

または、任意のコマンド。ls | xargsxargs出力のデフォルトの制限は〜4096文字ですが、たとえば、xargs -s 8192


| tr '\n' ' 'php exec関数を介して呼び出されたときに私のために働いていませんでした。それはtrを無視し、grepからの最後の一致を与えていました。| xargs働いた。
アダルシャ2015年

3
このソリューションには、入力からスペースを「食べる」という利点もあります。+1
ルネ

55

echo引用符なしのbash では、キャリッジリターン、タブ、および複数のスペースを削除します

echo $(cat file)

8
ここでは非常に過小評価されている答えですが、これは非常に単純で、魅力的なように機能し、末尾に改行も付いています。
Dangercrow 2017年

これは、使用する場合に特に便利ですIFS="$(printf '\n\t')"
aggsol 2017年

5
または単にecho $(<file)...エコーを使用することは、を使用するtr '\n' ' 'よりも優れているだけでなく、より優れています(\r\n行末を考える)。@aggsol言うことができますIFS=$'\n\t'
Normadize 2017

スペースなしでいかがですか?
DimiDak

22

これはあなたが望むものかもしれません

cat file | grep pattern | paste -sd' '

あなたの編集については、それが何を意味するのかよくわかりません。

cat file | grep pattern | paste -sd'~' | sed -e 's/~/" "/g'

(これは、で~発生しないことを前提としていますfile


2
@Stephanは、それcat fileが実際にcat、またはファイルであると仮定する必要はありませんでした。(質問には無関係だったので、その部分は変更しませんでした)
2015年

5

これは、コンマで区切られた出力を生成する例です。コンマは、必要なセパレータで置き換えることができます。

cat <<EOD | xargs | sed 's/ /,/g'
> 1
> 2
> 3
> 4
> 5
> EOD

生成する:

1,2,3,4,5

3

exエディタVimの一部)を使用する方法は次のとおりです。

  • Jすべての行およびOIN のp標準出力にRINT:

    $ ex +%j +%p -scq! file
  • J(ファイル内の)すべての行インプレースOIN:

    $ ex +%j -scwq file

    注:これにより、ファイルit-self内のすべての行が連結されます。


2

この問題を解決するために私が知っている最も速くて簡単な方法:

改行文字 \n をスペースで置き換えたい場合:

xargs < file

xargs1行あたりの文字数とすべての文字の合計数には独自の制限がありますが、増やすことができます。詳細は、次のコマンドを実行することで確認できます。xargs --show-limitsもちろん、マニュアルでも確認できます。man xargs

ある文字を別の文字に正確置き換える場合:

tr '\n' ' ' < file

1つの文字を多くの文字置き換えたい場合:

tr '\n' '~' < file | sed s/~/many_characters/g

まず、我々は、改行文字を置換\nチルダために~(またはテキストに存在しない別のユニークなキャラクターを選択)した後、我々は(他の文字とのチルダ文字を置き換えるmany_characters)、我々は、各チルダ(フラグのためにそれを行いますg)。


0

おそらくそれを行うための最良の方法は、出力を1行に生成する「awk」ツールを使用することです

$ awk ' /pattern/ {print}' ORS=' ' /path/to/file

すべての行をスペース区切り文字で1つにマージします


これ{print}はデフォルトのawkアクションなので必要ありません。
スターク

0

次に、別の簡単な方法を示しawkます。

# cat > file.txt
a
b
c

# cat file.txt | awk '{ printf("%s ", $0) }'
a b c

また、ファイルに列がある場合、これは特定の列のみを連結する簡単な方法を提供します。

# cat > cols.txt
a b c
d e f

# cat cols.txt | awk '{ printf("%s ", $2) }'
b e

-1

Red Hat Linuxでは、ただechoを使用します。

echo $(cat / some / file / name)

これにより、ファイルのすべてのレコードが1行で表示されます。


2
これは2015年にすでに回答されていますこの回答を複製しています。特に質問が7歳で、すでに8つの回答がある場合は、自分で投稿する前に回答を読んでください。
ミカエルB.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.