
次のように、数値.txtを含む数値を含むファイルがあります。
9374541632553 51243747879841 32030098896914 84654557358238 11000656847765
次の形式に変換したいと思います。
<item>9 3 7 4 5 4 1 6 3 2 5 5 3 <tag>out="9374541632553"
<item>5 1 2 4 3 7 4 7 8 7 9 8 4 1 <tag>out="51243747879841"
<item>3 2 0 3 0 0 9 8 8 9 6 9 1 4 <tag>out="32030098896914"
<item>8 4 6 5 4 5 5 7 3 5 8 2 3 8 <tag>out="84654557358238"
<item>1 1 0 0 0 6 5 6 8 4 7 7 6 5 <tag>out="11000656847765"
変換するには、次のコマンドを使用しています。
cat numbers.txt | while read line; do sed -r "s/([0-9])/\1/g; s/([0-9])/\1 /g ; s/^/<item>/g; s/$/<tag>out="\$line/g" ; done
しかし、私が得た結果は次のとおりです。
<item>5 1 2 4 3 7 4 7 8 7 9 8 4 1 <tag>out="9374541632553
<item>3 2 0 3 0 0 9 8 8 9 6 9 1 4 <tag>out="9374541632553
<item>8 4 6 5 4 5 5 7 3 5 8 2 3 8 <tag>out="9374541632553
<item>1 1 0 0 0 6 5 6 8 4 7 7 6 5 <tag>out="9374541632553
<item>3 3 2 1 6 7 8 2 0 9 3 8 4 2 <tag>out="9374541632553
最後の列が行単位の値ではなく、最初の行だけを印刷する理由を誰でも教えてもらえますか?
出力の最初の行はどうですか?
必要な出力を得るには、必要なコマンドを解釈します。
答え1
何も繰り返すことなくこれを行うことができますawk
。
awk '{a=$1;gsub(/./,"& ",$1); print "<item>"$1"<tag><out>=""\""a"\""}' numbers.txt
出力:
<item>9 3 7 4 5 4 1 6 3 2 5 5 3 <tag><out>="9374541632553"
<item>5 1 2 4 3 7 4 7 8 7 9 8 4 1 <tag><out>="51243747879841"
<item>3 2 0 3 0 0 9 8 8 9 6 9 1 4 <tag><out>="32030098896914"
<item>8 4 6 5 4 5 5 7 3 5 8 2 3 8 <tag><out>="84654557358238"
<item>1 1 0 0 0 6 5 6 8 4 7 7 6 5 <tag><out>="11000656847765"
説明する:
- まず、最初のフィールドを
$1
変数に保存します。a
- 各文字を
$1
独自の文字に置き換えて、その後にスペースを入れます。 - 最後に、必要な順序ですべてを印刷します。
- 少しトリッキーな部分は、
\"
引用符自体が必要な場所に二重引用符を印刷することです。
編集(最後のスペースを削除):
awk '{a=$1;gsub(/./,"& ",$1); printf "<item>"$1"\b<tag><out>=""\""a"\"\n"}' numbers.txt
<item>9 3 7 4 5 4 1 6 3 2 5 5 3<tag><out>="9374541632553"
<item>5 1 2 4 3 7 4 7 8 7 9 8 4 1<tag><out>="51243747879841"
<item>3 2 0 3 0 0 9 8 8 9 6 9 1 4<tag><out>="32030098896914"
<item>8 4 6 5 4 5 5 7 3 5 8 2 3 8<tag><out>="84654557358238"
<item>1 1 0 0 0 6 5 6 8 4 7 7 6 5<tag><out>="11000656847765"
答え2
どちらも標準入力read
からデータを取得するからです。sed
while
ループ内のread
最初の行を.で$line
開始sed
します。他の入力を提供しないので、stdinから読み込みます。したがって、cat numbers.txt
残りのsed
入力が消費されます。まだwhileループの最初の反復にあるため、$ line変数は変更されません。
私はこれにPerlを使います:
perl -lne '($spaced = $_) =~ s/./$& /g; print qq{<item>$spaced<tag>out="$_"}' numbers.txt
答え3
sedですべての操作を実行する1つの方法は次のとおりです。
sed '
h;
s/./& /g;
s/.*/<item>&<tag>out=/;
G;
s/\n\([0-9]*\)/"\1"/;
' numbers.txt
答え4
これはどうですか...
cat numbers.txt | while read line; do echo $line | sed -r "s/([0-9])/\1/g; s/([0-9])/\1 /g ; s/^/<item>/g; s/$/<tag>out=\"$line\"/g" ; done
または、
cat numbers.txt | while read line; do echo "<item>$(echo $line | fold -w1 | paste -s -d' ') <tag>out=\"$line\""; done