web-dev-qa-db-ja.com

ファイルの特定の行にテキストを挿入しますか?

ファイルの特定の行にテキストを挿入するにはどうすればよいですか?私が使用できる最も簡単な方法は何ですか? (bash、sed、awk?)

やりたいことは簡単かもしれませんが、どこから始めたらいいのかわかりません。これを手動で実行するには時間がかかりすぎます(後でExcel/Calcで使用するために変更する必要があるファイルが非常に多くあります)。

これが私の入力ファイルの例です:

4.06
4.05
5.04
4.06
34.50
56.06
45.33
36.44

そして、私はこのようなものが欲しいです(1行目と5行目の前にテキストを挿入してください):

Exp1    
4.06
4.05
5.04
4.06
Exp2
34.50
56.06
45.33
36.44

これどうやってするの?

4
Armen
awk 'NR==1{print "Exp1"}NR==5{print "Exp2"}1' file

末尾の1は{print}を意味します。

sed '1i\
Exp1
5i\
Exp2
' file

より多くの数値に拡張したい場合は、awkを使用すると簡単です。

awk 'NR%4==1{print "Exp"++i}1' file

数字が違うので、sedはその仕事に適したツールではないというだけです。それは可能ですが、きれいではありません。


学術的な好奇心として、これはsedにあります:

sed '1{ 
    h
    s/^.*$/Exp0/
    x   
}
x
s/^4//
s/^3/4/
s/^2/3/
s/^1/2/
/^E/ { 
    s/$/|/
    :x
    s/0|/1/
    s/1|/2/
    s/2|/3/
    s/3|/4/
    s/4|/5/
    s/5|/6/
    s/6|/7/
    s/7|/8/
    s/8|/9/
    s/9|/|0/
    tx
    s/^Exp|/Exp1/
    p
    s/^/1/
}
x' file
6
Kevin

各実験(ここでも、私が想定している)のデータポイント(私が想定している)の数が常に4である場合、このPerlワンライナーを使用できます。

Perl -ple '$. % 4 == 1 and print "Exp", ++$i' your_file

仕組み

  • -pスイッチは、指定したファイルを1行ずつ(デフォルトで)ループし、指定したコードを実行した後に各行を出力するようにPerlに指示します。
  • -lスイッチは、各printステートメントに改行(デフォルトでは)を自動的に追加するようPerlに指示します。
  • -eスイッチは、実行するコード(ファイルの各行が出力される前に実行されるコード)の後に続くものがPerlに通知します。
  • 特殊変数$.は、現在処理されている行番号を保持します。その行番号が4を法とする1($. % 4 = 1)に一致する場合は、その前にExp #を挿入する必要があることを意味します。
  • したがって、$. % 4 == 1をテストし、それがtrueの場合はExp ++$i\nを出力します(\n-lスイッチによって追加されています)。これは、未定義の変数が最初に整数として使用されたときにPerlによってゼロの値が与えられるため、機能します。

複数のファイルで機能させるため

  • 複数のファイルを一度に処理する場合、$.変数はその値をリセットしません。明らかに、これはあなたが望むものではありません。 continueブロックを操作できるように、上記のワンライナーで-pによって作成された暗黙のループを明示的に書き込むことで、これを回避できます。

    Perl -le '
        while(<>){
            $. % 4 == 1 and print "Exp ",++$i
        } continue {
            print;             # Print the current line
            if(eof){           # If the next line is the end-of-file
                close ARGV ;   # Close the current filehandle to reset $.
                $i = 0     ;   # Reset the experiment counter if you need
            }
        }
    ' list_of_your_files
    

メモ

  • 上記の両方のソリューションは、変更されたファイルを標準出力に出力します。編集をエミュレートする(つまり、ファイル自体を編集する)には、-iスイッチを追加します。

    Perl -pi -le '$. % 4 == 1 and print "Exp", ++$i' your_file
    
    • 他のソリューションについても同様に進めます。
    • バックアップファイルを作成するために使用する拡張子としてそれ以降を解釈するため、-iの直後に別のスイッチを配置しないでください。

    • 最初に-iなしでテストし、満足のいく結果が得られたら追加することをお勧めします。

2
Joseph R.

ファイル内の指定された行の先頭にコメント(#)記号を追加する方法を検索しているこの質問を見つけました。上記の例と他のいくつかを使用して、これが指定された行に何かを出力するawkコマンドであることがわかりました。

awk 'NR==1{print "#"$0; next}1' <file

NR==1は考慮すべき行です。
print "#"は追加するものです$0は、指定された番号の行の残りを含む文字列に挿入しますnextは、その行をスキップするように指示します(印刷されている場合、それ以外の場合は2回取得されます) )そして上記のように、末尾の1はファイルの残りを挿入します。

0
sibaz

あなたは外部言語を必要としません、いくつかの標準的なコマンドでうまくいくことができます。たとえば、Origin.txtの5行目に何かを挿入するには、次のようにします。

tmpfile=`mktemp`
head -n4 Origin.txt > $tmpfile
echo "I'm line 5 now" >> $tmpfile
tail -n +5 Origin.txt >> $tmpfile
mv $tmpfile Origin.txt
0
jesjimher