我有一个包含数字的文件,其中包含numbers.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 中完成整个操作的一种方法:
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