web-dev-qa-db-ja.com

テキスト処理-2行ごとにコンマで結合します

ファイルに1000行を超える行があります。ファイルは次のように始まります(行番号が追加されます)。

Station Name
Station Code
A N DEV NAGAR
ACND
ABHAIPUR
AHA
ABOHAR
ABS
ABU ROAD
ABR

これをファイルに変換する必要があります。2行ごとにコンマで区切ってエントリを結合します。最終的なデータは次のようになります

Station Name,Station Code
A N DEV NAGAR,ACND
ABHAIPUR,AHA
ABOHAR,ABS
ABU ROAD,ABR
...

私が試していたのは、シェルスクリプトを記述してから、その間にカンマを入れてechoしようとすることでした。しかし、私は、ここでの仕事がsed/awkにあるかもしれない、より簡単で効果的なワンライナーが実行すると思います。

何か案は?

38
mtk

単にcat(猫が好きなら;-))とpasteを使ってください:

cat file.in | paste -d, - - > file.out

説明:pasteは、いくつかのファイルから読み取り、対応する行を貼り付けます(最初のファイルの行1と2番目のファイルの行1など)。

paste file1 file2 ...

ファイル名の代わりに、-(ダッシュ)を使用できます。 pasteは、file1(stdin)の最初の行を取得します。次に、file2(これもstdin)から最初の行を読み取ります。ただし、stdinの最初の行は既に読み取られて処理されているため、入力ストリームで待機するのはsecond stdinの行であり、pasteは最初の行にうまく接着します。 -dオプションは、区切り文字をタブではなくコンマに設定します。

または、

cat file.in | sed "N;s/\n/,/" > file.out

追伸はい、上記を簡略化して

< file.in sed "N;s/\n/,/" > file.out

または

< file.in paste -d, - - > file.out

catを使用しないという利点があります。

ただし、このイディオムは使用しませんでした意図的に、明快さの理由から-冗長ではなく、cat(CATS ARE Nice)が好きです。したがって、編集しないでください。

または、猫よりも貼り付けを希望する場合(貼り付けはファイルを水平に連結するコマンドで、猫は垂直に連結するコマンドです)、次のように使用できます。

paste file.in | paste -d, - -
45
January

ここに着陸した人がすべての行をCSVの1つのライナーにまとめようとしている場合は、

cat file | tr '\n' ','
8
Darren Weber
paste -sd ',\n' file.in > file.out

また、ある文字を別の文字に置き換えるだけなので(他のすべての改行をコンマで置き換える)、適切な入力ファイルを処理できることにも注意してください。

paste -sd ',\n' file.in 1<> file.in

(ただし、一部のエミュレートされたPOSIX pasteが非UNIXの方法で処理する可能性があるCRLFターミネーター(Microsoftのターミネーターなど)がある非UNIXシステムでは機能しない可能性があることに注意してください)

3
sed 'N;s/\n/,/' file

Sedを使用して、2行ごとにjoin(N)し、newline(\ n)を "、"に置き換えます。

3
Guru

以下は、純粋なBashを使用したワンライナーです(ただし、何百万ものコマンドが実行される可能性があります)。

(IFS=; while read -r name; do read -r code; printf '%s\n" "$name,$code"; done < file.in) > file.out

IFSを保存して復元する必要がないように、サブシェル(括弧)を使用しています。ソースが提供されている場合にユーザー環境を台無しにしないようにするために、どちらを行うべきか。別の方法として、IFS= read -r nameIFS= read -r codeのように、新しいIFSをreadにのみ渡すこともできます。

ループ内のすべてのコマンドがシェルに組み込まれているという事実は、そのパフォーマンスを許容できるものにし、小さなファイルの他のソリューションよりもさらに高速です。しかし、多くの人はそれを悪い習慣だと考え、他のものに一般化するときは注意が必要です。

2
Deleted

完全な回答セットの場合、考えられるawkソリューションは次のとおりです。

awk 'NR%2==1 {printf $0","} NR%2==0 { print $0}' *file*
2
Bernhard

awkidiomの古い古い栗

awk '{ORS=NR%2?",":"\n";print}' file
Station Name,Station Code
A N DEV NAGAR,ACND
ABHAIPUR,AHA
ABOHAR,ABS
ABU ROAD,ABR
1
iruvar

prを使用したPOSIXソリューション:

pr -2 -a -t -s, file

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pr.html

0
Steven Penny

例えば:

seq 0 70 | xargs -L 2 | sed 's/ /,/g'

出力:(注:xargs -L number_of_columnsは、2行ごとだけでなく、ほとんどすべての列でうまく機能します)

0,1
2,3
4,5
6,7
8,9
10,11
12,13
14,15
16,17
18,19
20,21
22,23
24,25
26,27
28,29
30,31
32,33
34,35
36,37
38,39
40,41
42,43
44,45
46,47
48,49
50,51
52,53
54,55
56,57
58,59
60,61
62,63
64,65
66,67
68,69
70
0
jmunsch

Perlでも可能です。

Perl -pe 's/^\d+\.\s+//;$.&1?chomp:print","' file

0
daisy