Ubuntu端末を使用していますが、ファイルの特定の行(11番目の場所)を最初の行に移動してから、最終結果を新しいファイルに転送する必要があります。元のファイルには数百行が含まれています。
これまでsedコマンドツールを試してみましたが、目的の効果が得られませんでした。これが私が今まで得たものです:
[mission 09] $ sed -n -e '1p' -e '11p' bonjour > bonjour2
ただし、新しいファイルでは最初の行と11行目のみが表示されます。しかし、新しいファイルが残りの元の行と一緒に希望のリビジョン位置を持つことを望みます。
入力する:
English: Hello
Turkish: Marhaba
Italian: Ciao
German: Hallo
Spanish: Hola
Latin: Salve
Greek: chai-ray
Welsh: Helo
Finnish: Hei
Breton: Demat
French: Bonjour
希望の出力
French: Bonjour
English: Hello
Turkish: Marhaba
Italian: Ciao
German: Hallo
Spanish: Hola
Latin: Salve
Greek: chai-ray
Welsh: Helo
Finnish: Hei
Breton: Demat
どんな提案がありますか?
答え1
使用(およびed
派生行エディタ):sed
grep
printf '%s\n' '11m0' 'w bonjour2' 'q' | ed -s bonjour
11m0
これにより、ファイルに編集コマンドが適用され、最初の行の前に11行目が移動します。その後、生成された文書がファイルに書き込まれ、bonjour2
終了します。
または:
printf '%s\n' '11m0' ',p' 'Q' | ed -s bonjour >bonjour2
...コマンドを使用して特定のファイルに書き込むのではなく、ファイルed
全体を標準出力として印刷します。その後、結果は新しいファイル名にリダイレクトされます。この,p
コマンド(略称1,$p
)は、文書全体を標準出力に出力してQ
強制終了します(文書が変更された場合でも)。
文書を所定の場所に変更するには(元のファイルの変更など)、結果をファイル自体に書き換えます。
printf '%s\n' '11m0' 'wq' | ed -s bonjour
上記の変形の1つの実行例:
$ printf '%s\n' '11m0' ',p' 'Q' | ed -s bonjour >bonjour2
$ cat bonjour2
French: Bonjour
English: Hello
Turkish: Marhaba
Italian: Ciao
German: Hallo
Spanish: Hola
Latin: Salve
Greek: chai-ray
Welsh: Helo
Finnish: Hei
Breton: Demat
いつも動いて最後行を一番上に移動するには、代わりに$m0
を使用してください11m0
。常に文字列で始まる行を移動するには、をFrench:
使用します/^French:/m0
。
答え2
sed -n '1h;2,10H;11G;11,$p'
最初の行はh
改行のためにコピーされてH
から10に追加されます。
存在する11行目、予約済みスペースの確保
~から11終了して印刷します。
]# sed -n '1h;2,10H;11G;11,$p' bonj
French: Bonjour
English: Hello
Turkish: Marhaba
Italian: Ciao
German: Hallo
Spanish: Hola
Latin: Salve
Greek: chai-ray
Welsh: Helo
Finnish: Hei
Breton: Demat
これは良いです:
]# seq 20 | sed -n '1h;2,10H;11G;11,$p'
11
1
2
3
4
5
6
7
8
9
10
12
13
14
15
16
17
18
19
20
例を挙げてみましょう。
]# sed -e 1p -e 11p -n bonj
English: Hello
French: Bonjour
...-n
最後のスイッチは両方の式で動作することを示すためのものです。
私も-n
、それなら1h;2,10H
これは、これは1,10H
、これは範囲行番号と「hold」(保存)コマンド。まだ何も印刷されていません。
11,$p
もう一つの範囲です。 11行目では、予約ステータス(例:1-10)で返したばかりの内容「11G」を印刷して11行目に追加します。
$までの12行目は-n
。
私は-e
あなたのように2つのことをする必要があります:
sed -n -e '1h;2,10H' -e '11G;11,$p'
1,10から保留し、11,$から印刷します。
11行目が最初にありG
、次にp
これが重要です。
]# seq 20 | sed -n -e '1h;2,10H' -e '11,$p;11G'
11
12
13
14
15
16
17
18
19
20
ここで、12行目は11行目に印刷された内容を消去します。
パラメータを持つ関数として
11行目は常に "putfirst"関数のために退屈です:
]# declare -f putfirst
putfirst ()
{
e="1h;2,$(($1-1))H;${1}G;${1},\$p";
sed -ne "$e" $2
}
2つのステップ:文字列を生成し、次にsedを呼び出します。 「$」には2つの意味があります。 「p」は変数ではありません!
有効な最低数字は次のとおりです。
]# seq 7 | putfirst 3
3
1
2
4
5
6
7
または、オリジナルの「bonj」ファイルを使用してください。
]# putfirst 4 bonj | putfirst 6 |head -4
Latin: Salve
German: Hallo
English: Hello
Turkish: Marhaba
これは2つの連続したsedですが、2つの作業が完了しました。
真珠
perl -ne '$n++; $h.=$_ if $n<11; print $_.$h if $n==11; print if $n>11' <(seq 20)
一部のスクリプトと同様に、ファイル名が必要で、オプションは必要ありません。
$want=11 ;
while (<>) {
$n++ ;
if ($n < $want) # before $want: store line
{ $lowlines .= $_ ;
next } # next line (avoids 'else')
if ($n == $want) # at line $want: append stored lines to $_
{ $_ .= $lowlines }
print ; # print $_ for $n not less than $want
}
AWK(Edから盗んだのです(編集者ではありません!))
NR < 11 {
buf[NR] = $0; next
}
NR >=11 {
print
if (NR == 11) {
for (i=1; i<11; i++) { print buf[i] }
}
}
私NR
は増加の代わりに使用してn
プロセスをより明確にします。同じ「トリック」:next
ダウンストリームを単純化します。
そしてperl -n
$n++ ;
$tmp = $tmp . $_ if $n < 11 ;
print $_ . $tmp if $n == 11 ;
print $_ if $n > 11 ;
これが最良の形式です。対称。
答え3
私が正しく理解したら、11行目だけを最初の行に移動したいと思います。
したがって、原本が次のような場合
Original line 1
Original line 2
...
Original line 18
Original line 19
Original line 20
それから結果は
Original line 11
Original line 1
Original line 2
...
Original line 9
Original line 10
Original line 12
Original line 13
...
Original line 19
Original line 20
これは次のことで達成できます。二つファイルを繰り返しますが、最初のパスは短くなる可能性があるため、あまりにも恐ろしいことはありません。
( sed -n '11 {p;q}' file ; sed 11d file ) > newfile
デフォルトでは、最初のsed
コマンドは行11を印刷してから終了します。 2番目sed
のコマンドは各行を印刷します。とは別に11号線。
その結果、行11は実際には新しいファイルの前に移動します。
答え4
そしてPOSIX sed
:
$ sed -e '1,11!b' -e '11!H;1h;11!d;G' file
使用perl
:
$ perl -lne '
push(@A,$_),next if $. < 11;
print for $_, splice @A;
' file
使用bash
:
$ (head -n 11 - | tee log | tail -n 1 -; head -n 10 log; cat -;) < file