我有一个输入文件,每行总是有3个值,用“…”分隔
1,2,3 4,5,6 ....
每一行都应该粘贴在一个模板文件中,每一行都要有一个自己的文件,用连续数字写,比如01.txt 02.txttemplate.txt
<wpt col="value1" cal="value2"><name>value3</name></wpt>
我如何才能做到这一点?在这台机器上,我只能使用shell脚本。没有Python或其他语言可用,也不能安装
qnakjoqk1#
printf
c=0 while IFS=, read -r c1 c2 c3; do ((c++)) printf -v count '%.2d' $c printf '<wpt col="value%d" cal="value%d"><name>value%d</name></wpt>\n' \ $c1 $c2 $c3 > "$count.txt" done < file
envsubst
man envsubstenvsubst -替换shell格式字符串中的环境变量
man envsubst
cat template.tpl <wpt col="value$c1" cal="value$c2"> <name>value$c3</name></wpt>
c=0 while IFS=, read -r c1 c2 c3; do ((c++)) printf -v count '%.2d' $c export c1=$c1 c2=$c2 c3=$c3 envsubst < template.tpl > "$count.txt" done < file
然后
ls -1 *.txt
nzk0hqpo2#
一种使用awk的方法,使用sprintf化输出文件名中的数字。请记住,这将覆盖具有相同名称的现有文件。
awk
sprintf
% awk -F ',' '{ nr=sprintf("%02d", NR) print "<wpt col=\""$1"\" cal=\""$2"\"><name>"$3"</name></wpt>" > (nr".txt"); close(nr".txt") }' file
或,包括阅读 template.txt 文件
% awk -F ',' 'NR==FNR{tem=$0; next} {nr=sprintf("%02d", FNR) sub(/col=.* /, "col=\""$1"\" ", tem) sub(/cal=.*\"><name/, "cal=\""$2"\"><name", tem) sub(/<name>.*<\/name>/, "<name>"$3"</name>", tem) print tem > (nr".txt"); close(nr".txt")}' template.txt file
结果
% cat 01.txt <wpt col="1" cal="2"><name>3</name></wpt> % cat 02.txt <wpt col="4" cal="5"><name>6</name></wpt>
wj8zmpe13#
这可能对你有用(GNU sed和split):
sed -E 's/(.*),(.*),(.*)/<wpt col="\1" cal="\2"><name>\3<\/name><\/wpt>/' file | split -l1 --add=.txt --numeric=01 - ''
将文件的每一行操作为所需的格式,然后将每一行拆分为一个单独的文件。
dxxyhpgq4#
通常情况下,我会先等着看你解决问题的尝试,这样我就可以帮助你的代码,但既然你已经有了答案...
$ cat tst.awk BEGIN { FS="," } NR==FNR { tmplt = $0 ORS gsub(/value[0-9]+/,"%s",tmplt) next } { out = sprintf("%02d.txt", FNR) printf tmplt, $1, $2, $3 > out close(out) }
$ awk -f tst.awk template.txt file
$ head 0*.txt ==> 01.txt <== <wpt col="1" cal="2"><name>3</name></wpt> ==> 02.txt <== <wpt col="4" cal="5"><name>6</name></wpt>
上面的内容可以使用任何awk,并且假设模板行不包含任何printf字符,例如%s和value[0-9]+,只在所需的上下文中匹配。
%s
value[0-9]+
t40tm48m5#
别浪费时间一个一个做。只需使用awk大规模生成printf语句,然后使用轻量级shell一次性执行所有语句(额外的好处是在awk中不必不间断地关闭文件):
gfind . -type f -print0 | xargs -0 grm -v ls -nAlFrt
removed './01.txt' removed './02.txt' removed './03.txt' total 0
echo $'1,2,3\n4,5,6\n7,8,9' | mawk '$!NF=sprintf("printf \47%%s\47 \47<wpt col=\"%s\" cal=\"%s\"><name" \ ">%s</name></wpt>\47 > \47%.2d.txt\47 ;",$1,$2,$3,NR)' FS=',' | gtee >( gpaste | gcat -n >&2; cat ) | dash
ls -nAlFrt
total 12 -rw-r--r-- 1 501 20 41 May 8 08:29 01.txt -rw-r--r-- 1 501 20 41 May 8 08:29 02.txt -rw-r--r-- 1 501 20 41 May 8 08:29 03.txt
for __ in *.txt; do gcat -n "$__" echo "\n\t$__\n" done
5条答案
按热度按时间qnakjoqk1#
使用
printf
使用shell模板文件,包含变量和
envsubst
:man envsubst
envsubst -替换shell格式字符串中的环境变量
然后
nzk0hqpo2#
一种使用
awk
的方法,使用sprintf
化输出文件名中的数字。请记住,这将覆盖具有相同名称的现有文件。
或,包括阅读 template.txt 文件
结果
wj8zmpe13#
这可能对你有用(GNU sed和split):
将文件的每一行操作为所需的格式,然后将每一行拆分为一个单独的文件。
dxxyhpgq4#
通常情况下,我会先等着看你解决问题的尝试,这样我就可以帮助你的代码,但既然你已经有了答案...
上面的内容可以使用任何awk,并且假设模板行不包含任何
printf
字符,例如%s
和value[0-9]+
,只在所需的上下文中匹配。t40tm48m5#
别浪费时间一个一个做。只需使用
awk
大规模生成printf
语句,然后使用轻量级shell一次性执行所有语句(额外的好处是在awk
中不必不间断地关闭文件):