web-dev-qa-db-ja.com

Geditまたはコマンドラインを使用して、テキストファイルの4行ごとに変更することはできますか?

テキストファイルをタブ区切りのスプレッドシートに変換しようとしています。私のテキストファイルは次のようなものです。

Dog
Cat
Fish
Lizard
Wolf
Lion
Shark
Gecko
Coyote
Puma
Eel
Iguana

GeditまたはLibreOfficeの標準の検索および置換機能を使用すると、行末をタブに簡単に置き換えることができます。しかし、タブのキャリッジリターンを入れ替えるだけで、次のようになります。

Dog   Cat   Fish   Lizard   Wolf   Lion   Shark   Gecko   Coyote   Puma   Eel   Iguana

しかし、私がする必要があるのは、次のようにすることです。

Dog   Cat   Fish   Lizard
Wolf   Lion   Shark   Gecko  
Coyote   Puma   Eel   Iguana

だから、タブの行末文字をすべて交換できますかexcept4行ごとに?

GeditやLibreOfficeのようなプログラム内の正規表現を使用して、そのような条件付き反復を実行できるかどうかはわかりません。したがって、これは何らかのコマンドライン関数である必要があります。始めるのに最適なツールが何であるかさえ明確ではありません。


更新:

次のコマンドを試しました。

sed 'N;N;N;s/\n/\t/g' file > file.tsv

paste - - - - < file > file.tsv

pr -aT -s$'\t' -4 file > file.tsv

xargs -d '\n' -n4 < inputfile.txt

しかし、結果のtsvファイルをLibreOfficeで開こうとすると、列が正しくありません。これが上記のコマンドを正しく実行していないことを意味するのか、LibreOfficeインポート機能で何か間違ったことをしているのかどうかはわかりません。

TSV opening in Calc

参考までに、望ましい結果は次のようになります。

Proper columns

11
Questioner

あなたはcouldsedなどのコマンドラインエディタを使用します

sed 'N;N;N;s/\n/\t/g' file > file.tsv

または、よりプログラム的に、GNU sedのn skip mアドレス演算子を使用して、結合する各行にバックスラッシュ行継続文字を追加します。そして、継続的な行に参加するための古典的なワンライナーでそれに続きます:

sed '0~4! s/$/\t\\/' file | sed -e :a -e '/\\$/N; s/\\\n//; ta'

たとえば、 Sed One-Liners Explained を参照してください。

  1. バックスラッシュ「\」で終わる場合、次の行を追加します。

    sed -e :a -e '/\\$/N; s/\\\n//; ta'
    

しかし、私見は、他の標準的なテキスト処理ユーティリティのいずれかで簡単になります。

paste - - - - < file > file.tsv

-の数は列の数に対応します)または

pr -aT -s$'\t' -4 file > file.tsv

(出力を複数のタブで区切ってもかまわない場合は、-s$'\tを省略できます)。


元のファイルにはWindowsスタイルのCRLF行末があるため、観察している奇妙な再インポート動作はほぼ確実です。 Windowsのファイルを操作する必要がある場合は、さまざまな方法でコマンドへの変換をロールバックできます。

tr -d '\r' < file.csv | paste - - - -

または

sed 'N;N;N;s/\r\n/\t/g' file.csv

前者はすべてのキャリッジリターンを削除しますが、後者は各新しい行の終わりにCRを保持します(目的のエンドユーザーがWindowsを使用している場合に必要な場合があります)。

16
steeldriver

xargsを使用して、4つの行を常に1つにグループ化し、それぞれを1つのスペースで区切ることができます。

xargs -d '\n' -n4 < inputfile.txt

-d '\n'は、入力区切り文字を改行文字に設定します。そうしないと、スペースで改行されます。とにかく入力行ごとに1つのWordしかない場合は、これを省略することもできます。
-n4は、引数番号(出力行ごとの入力項目の数)を4に設定します。

出力:

Dog Cat Fish Lizard
Wolf Lion Shark Gecko
Coyote Puma Eel Iguana

または、スペースではなくセパレータとしてタブを使用する場合は、後でタブを置き換えることができます。ただし、入力行にスペースが含まれている場合、それらも置換されます。

xargs -d '\n' -n4 | tr ' ' '\t'

出力(ブラウザ/端末のタブ幅に応じて表示):

Dog Cat Fish    Lizard
Wolf    Lion    Shark   Gecko
Coyote  Puma    Eel Iguana
13
Byte Commander

以下も使用できます。

awk -v ORS="" '{print $1; print NR%4==0?"\n":"\t"}' file > file.tsv 

2つのawk組み込み変数は次のとおりです。

  • ORSO utput R ecord S eparator(default = newline)。各印刷コマンドの最後に追加されます。
  • NRN現在のR owwは処理中です。

このコマンドは、各行について、最初の(そしてここだけの)列の内容を表示します。次に、NRの4による除算の残りをテストして、改行またはタブを追加することを選択します。

3
arauk

別の最短のawkアプローチ:

awk '{printf $0 (NR%4?"\t":"\n")}' infile

このprintf次と次と...が続く唯一の列と、それぞれの後にTab \t文字がありますが、printfa \newline文字N umber of R ecordが4(ここで、NR%4は(false)を返します三項演算子condition(s)?when-true:when-falseが行っていることです。)

3
αғsнιη

これに対する私の解決策は、sedsedの組み合わせを使用することです。まず、次のソリューションを使用して、>などの特殊文字で4行ごとにマークを付けることができます。

この場合、5行目から開始し、その後4行ごとにマークを付けます。 GNU sedで、アドレス5~4として指定できます。次のコマンドを使用できます。

sed '5~4s/^/>/' file1 > file2

次に、改行を削除する必要があります。これは、sedループで実行できます。

sed ':a;N;s/\n/ /;ba' file2 > file3

trなどを使用して、改行を他の文字に変換する簡単な方法があります。

tr '\n' ' ' < file2 > file3

どちらにしても、2つを組み合わせると

Dog   Cat   Fish   Lizard   >Wolf   Lion   Shark   Gecko   >Coyote   Puma   Eel   Iguana

sedバージョンは末尾の改行を残しますが、trバージョンは残しません)

その後は、挿入した特殊文字を改行に変換するだけで済みます。たとえば、 を参照してください。タブ区切りファイルを変換して、newlines を使用します。この場合、>を改行に変更します。

sed 'y/>/\n/' file3 > outfile

yコマンドはtrと同じ機能を実行し、1つの文字を別の文字に変換しますが、sコマンドも同様に使用できます。 sを使用する場合、行(sed 's/>/\n/g')の各一致を操作するにはgが必要です。

2つの中間ファイルを作成する代わりに、パイプを使用できます。

$ sed '5~4s/^/>/' file | sed ':a;N;s/\n/ /;ba' | sed 'y/>/\n/'
Dog Cat Fish Lizard 
Wolf Lion Shark Gecko 
Coyote Puma Eel Iguana

末尾のスペースが問題になる場合は、別のコマンドを追加して削除できます。

| sed 's/ $//'
3
spaceman117X

「完全性」のために here's 純粋なbashソリューション:

#!/usr/bin/env bash

sep=$'\t'

while read one \
      && read two \
      && read three \
      && read four
do
  printf "%s\n" "$one$sep$two$sep$three$sep$four"
done

IFSが適切に設定されていると仮定すると、スペースでも動作します(デフォルトではAFAIKである必要があります)。さらに、Ithinkこれは移植可能なシェルスクリプトであり、POSIX互換のシェルで動作する可能性さえあります。

2
Daniel Jour

Vimマクロ(qで記録)が操作を適用し、3行スキップします。次に、そのマクロをn回実行するだけです。

例えば:

qq $ J i <TAB> <ESC> $ J i <TAB> <ESC> $ J i <TAB> <ESC> ^^ j qq 100 @q
2
rackandboneman

Geditソリューションを要求したので、次のように機能するはずです。

見つける:

(\w+)[\r\n]+(\w+)[\r\n]+(\w+)[\r\n]+(\w+)[\r\n]+

と置換する:

\1\t\2\t\3\t\4\n

正規表現のチェックボックスがマークされていることを確認してください。

使い方:

最初の手順は、\ w +を使用して一連のWord文字を検索し、式をかっこで囲むことにより変数\ 1に結果をキャプチャすることです。

(\w+)

次に、一連の行末文字、\ rと\ n、またはCRとLFを検索します。 Windows形式のファイルは両方を使用するため、これらの2つの文字を角括弧で囲むことで文字クラスを作成します。プラス記号は、1つ以上の文字を検索します。

[\r\n]+

最後に、これをさらに3回繰り返し、後続の各Wordを変数\ 2、\ 3、および\ 4に格納します。これにより、式による置換が簡単になります。必要な書式設定に適した場所に、タブ文字\ tと改行文字\ nを配置するだけです。

2
Jason Wood