仮定:
これが私が表示する唯一のテキストです。残りのテキストには[表示されていません]より多くのデータがありますが、これは問題です。テキストは少しきれいで、スペース、タブ、Unicodeでいっぱいで、きれいではなく、次のようにする必要があります。したがって、この正確なテキストをコピーして貼り付けるのはうまくいきません[マークアップ形式]:
私は持っています一部次のテキスト:
*** *
more text with spaces and tabs
*****
1
Something here and else, 2000 edf, 60 pop
Usd324.32 2 Usd534.22
2
21st New tetx that will like to select with pattern, 334 pop
Usd162.14
*** *
more text with spaces and tabs, unicode
*****
私は次の明示的なテキストを取得しようとしています。
1 Something here and else, 2000 edf, 60 pop Usd324.32
newline
そして、whitespace
次のコマンドは次のもののみを取得します1
。
grep -E '1\s.+'
また、私は新しい接続を使用してこれを実行しようとしました。
grep -E '1\s|[A-Z].+'
しかし、うまくいきません。grep
テキストの他の部分から同様のパターンを選択し始めました。
awk '{$1=$1}1' #done already
tr -s "\t\r\n\v" #done already
tr -d "\t\b\r" #done already
どうやってキャッチできますか?
- 1つをつかむ
newline
- その後、2行目全体をつかむ1
newline
- 番号をつかんで
$Usd324.34
削除してくださいUsd
答え1
pcregrep
Ultilineモードとキャプチャグループの内容を出力する機能がありますM
。o
$ pcregrep -Mo1 -o2 -o3 --om-separator ' ' '^(1)\n(.*)\n\h*Usd(\H+)' file
1 Something here and else, 2000 edf, 60 pop 324.32
答え2
- 「1」とオプションのスペースのみを含む行で始まる3行を連結して変更するには、次の手順を実行します。
$ perl -0777ne '/^1\s+(.*?)\h*\n\h*Usd(\H+)/imsg && printf "1 %s %s\n", $1, $2' input.txt
1 Something here and else, 2000 edf, 60 pop 324.32
この-0777
オプションは、Perlが一度に1行ずつ読み込むのではなく、ファイル全体を一度に読み取るように指示します。 -n
同様の方法で入力を処理するように指示しますsed -n
。 -e
Perlに、次の引数がスクリプトであることを伝えます。
正規表現がテキストと一致する場合は、REキャプチャグループでキャプチャしたテキストを目的の形式で印刷します。
「オプションの末尾の空白」を一致させることは、あなたの質問からコピーして貼り付けたサンプルファイルに複数行に末尾の空白文字があるという事実を処理することです。これが元のファイルにあったのか、それとも質問に貼り付けたアーティファクトなのかはわかりません。重要ではありません。スクリプトは、末尾の空白があるかどうかにかかわらず、同じように動作します。
- 数字とオプションのスペースのみを含む行で始まる3行のグループを組み合わせて変更するには、次の手順を実行します。
$ perl -n -e 'if (/^\d+\s*$/) {
chomp; $_ .= " " . <>;
chomp; $_ .= " " . <>;
s/\s{2,}/ /g;
s/Usd(\H+).*/$1/i;
print
}' input.txt
1 Something here and else, 2000 edf, 60 pop 324.32
2 21st New tetx that will like to select with pattern, 334 pop 162.14
行にオプションの末尾のスペースが含まれている数値のみが含まれる場合は、次の2行を取得して現在の行に追加してから修正して印刷します。
chomp
各行の末尾から改行文字を削除し、<>
次の入力行を読みます。次の2行を取得して追加するために2回実行されます。その後、連結行を2つの操作に変更しますs///
(最初の操作は2つ以上の空白文字を1つのスペースに減らし、2番目の操作は最初の "Usd \ H +"の後の行からすべての項目を削除し、リテラル文字列 " 「Usd」も削除します。印刷する前に最後のジョブが完了します(大文字と小文字を区別しません)。
\h
水平スペース文字に一致するPerl正規表現。 \H
逆です。どんなものにもマッチします。いいえ水平スペース。
- これら2つのperl one-linerは、元のサンプルデータと編集された質問の更新された例で動作し、同じ出力を生成します。
答え3
次のように使用できますawk
。
$ awk 'BEGIN {count = 0; ORS=" "} /^1$/ {found = 1; print; next; count++} found && count < 1 {count++; print; next} count == 1 {print $1; exit} END {printf "\n"}' < FILE
1 Something here and else, 2000 edf, 60 pop 324.32
または以下を使用してくださいgetline()
。
awk 'BEGIN {ORS=" "} /^1$/ {getline; print; getline; print $1} END {printf "\n"}' < FILE
答え4
sed
この仕事にも適しています:
sed -n '/^1 $/{h;n;H;n;s/^ *\([0-9.]*\).*/ \1/;H;g;s/\n//g;p}' sample