
次の内容を含む「SAMPLE.txt」というファイルがあります。
P1
10,9:6/123456
P2
blah blah
P1
10,9:5/98765
P2
blah
blah
P1
blah blah
P2
出力ファイル「RESULT.txt」が欲しい。
Value1:123456
Value2:98765
Value3:NULL
まず、P1とP2部分の間のコンテンツをインポートしてから、10,9 * /値を見つけて別の値として保存する必要があります。特定のP1-P2ブロックにこの値がない場合は、「NULL」として保存したいと思います。
上記のコードをshell / awkにどのように書きますか?
私はスクリプトに初めて触れました。
答え1
これは機能し、完全に移植可能です。
sed '\|^P1.*|!d;s||Value:|
:n
N;\|\nP2|!bn
s|:.*\n10,9[^/]*/|:|
s|\n.*||;s|:$|:NULL|'
プロセスは次のとおりです。
まず
^
扱います。P1
現在の行が
!
一致しない場合はd
削除されます。その場合は、次のよう
P1
に交換してください。Value:
:n
次に、extタグを設定してN
ext行を取得します。見つから
\nP2
ない場合は、extタグに戻り、見つかるまでもう一度やり直してください。!
b
:n
:.*\n10,9
次に、最初の発生/
まですべての文字の発生を削除します。\n
最初に使用可能なewlineと後続のすべての文字を削除します。:
最後の文字が後に続くコロンの場合、文字Value
列が挿入されますNULL
。
手順6と7が機能します。手順6では、\n
目的の数値文字列の前にあるewlineを削除しますが、そうでない場合は、次の\n
ewlineは次の文字列になりますValue:
。すべてステップ7に進みます。
これが実際に動作するものです:
sed '\|^P1.*|!d;s||Value:|
:n
N;\|\nP2|!bn
s|:.*\n10,9[^/]*/|:|
s|\n.*||;s|:$|:NULL|' <<\DATA
P1
10,9:6/123456
P2
blah blah
P1
10,9:5/98765
P2
blah
blah
P1
blah blah
P2
DATA
出力:
Value:123456
Value:98765
Value:NULL
答え2
使用perl
(ファイル全体をメモリに保存しても):
perl -0777 -ne 'while (/P1\n(.*?)\nP2/gs) {
printf "Value%d:%s\n", ++$n, $1 =~ /^10,9.*\// ? $'\'': "NULL"}'
答え3
一方perl
通行:
$ perl -F'/' -alne '
if (/P1/../P2/ and $_ !~ /^P/) {
print "Value@{[++$i]}:",$F[1]?$F[1]:"NULL";
}
' file
Value1:123456
Value2:98765
Value3:Null
解決策awk
:
$ awk -F'/' '/P2/{f=0};/P1/{f=1;next};f{print "Value"++i":"($2?$2:"Null")}' file
Value1:123456
Value2:98765
Value3:Null
答え4
みんなありがとうございます。ついに私の問題を解決したコードスニペットは次のとおりです。
nawk -v fname="${filename}" -F '/|:' '
function isnum(x){return(x==x+0)}
/P1/,/P3/{
# Found start increment i reset variables go to next line
if(/P1/){
++i
fid =""
count++
next
}
# Found end validate variable and print go to next line
if(/P3/){
printf "%s|",count
printf "%s|",isnum(fid)?fid:"NULL"
next
}
if(!fid && /36,59:*/)
{
fid = $NF
}
' ${filename} >>output.txt
しかし、もう別の問題が発生し、それに対して別のスレッドを作成しました。
あなたが助けることができる場合は、こちらのリンクをご覧ください。