「*」記号を使用して(その記号である必要はなく、特殊文字を使用して指示します)、これからテキストを編集するにはどうすればよいですか。
*berry
straw
rasp
blue
boysen
*
blahblah
blahblah
blahblah
*berry
straw
blue
*
blah
*table
vege
pingpong
*
これに:
strawberry
raspberry
blueberry
boysenberry
blahblah
blahblah
blahblah
strawberry
blueberry
blah
vegetable
pingpongtable
最初に一致するアスタリスクの後のすべての文字は、2番目のアスタリスクが見つかるまですべての行に配置されます。
私はこれについてどうやって行くことができますか? (sedまたはawkをお勧めしますが、別の方法が考えられる場合は、コードを教えてください!)
私はアスタリスクを含むすべての行を削除する方法を知っています、それは私が考えることができない文字配置部分です
このawk
コードで十分です:
awk -F'*' 'NF == 2 {label = $2; next} {$0 = $0 label} 1'
分解するには:
*
を使用します。この方法で、フィールドの数(NF
)を単純に調べて、ブロックの先頭または末尾に到達したかどうかを判断できます。label
に保存し、次の行に進みます。label
を現在の行に追加してから印刷します。ラベルが空の場合、ブロックの外側にいるため、効果はありません。そうでない場合、必要な出力を取得します。sed
では、削除する前に「特別な」行を保留スペースにコピーできます
sed -e '/^\*/{h;d;}'
ホールドスペースを後続の各パターンスペースに追加し、結果の改行文字とマーカー文字を置き換えます
-e '{G;s/\n\*//;}'
あなたのデータでテストし、
$ sed -e '/^\*/{h;d;}' -e '{G;s/\n\*//;}' file
strawberry
raspberry
blueberry
boysenberry
blahblah
blahblah
blahblah
strawberry
blueberry
blah
vegetable
pingpongtable
注:これは、2番目のアスタリスクが検出されても停止しません。まったく同じですが、次の*
に一致するまで*sometext
の後に何も付加されません。
Perlの方法は次のとおりです。
$ Perl -lne '/^\*(.*)/ || print "$_$1"' file
strawberry
raspberry
blueberry
boysenberry
blahblah
blahblah
blahblah
strawberry
blueberry
blah
vegetable
pingpongtable
-n
はPerlに入力ファイルの各行を読み取らせ、特殊変数$_
に保存します。-l
はi)後続の改行(\n
)各行からii)print
の各呼び出しに改行を追加します。 -e
は、各行に適用されるスクリプトです。
/^\*(.*)/
:アスタリスクで始まる行に一致し、アスタリスクの後のすべてを$1
として保存します(括弧が行うことです)。
|| print "$_$1"'
:||
は論理的なOR
です。したがって、print
は、現在の行がアスタリスクで始まっていない場合にのみ実行されます。その場合、現在の行($_
)を、現在$1
(アスタリスクに続くパターン)として保存されているものと一緒に印刷します。
いつものように、これを行うには多くの方法があります。愚かで非効率的なものですが、シェルの文字列操作機能を強調するものは次のとおりです。
$ while read line; do
[[ $line =~ ^\* ]] && pat="${line#\*}" || printf "%s%s\n" "$line" "$pat";
done < file
strawberry
raspberry
blueberry
boysenberry
blahblah
blahblah
blahblah
strawberry
blueberry
blah
vegetable
pingpongtable
while read line; do ... ; done < file
:これは、入力ファイルwhile
の各行を読み取り、$line
として保存する古典的なfile
ループです。[[ $line =~ ^\* ]] && pat="${line#\*}"
:行が*
で始まる場合、その後のすべてを削除します(これは${line#\*}
が行うことです。詳細については here を参照)、保存してください$pat
として。 * || printf "%s%s\n" "$line" "$pat";
:前のコマンドが失敗した(したがって、行がアスタリスクで始まらない)場合、行と$pat
の現在の値を出力します。私の好きなPythonを通して...
with open('/path/to/the/file') as f:
counter = False
for line in f:
if line.startswith('*') and not counter:
m = line.strip().lstrip('*')
counter = True
Elif line.startswith('*') and counter:
counter = False
Elif counter:
if not line.startswith('*'):
print(line.strip() + m)
else:
print(line.strip())
遅く来た。別のpython
アプローチがあります。
#!/usr/bin/env python2
with open('/path/to/file.txt') as f:
for lines in f.read().split('*'):
entries = lines.rstrip().split('\n')
for i in range(1, len(entries)):
print entries[i] + entries[0]