我尝试使用 sed 从ASCII文件中读取一行,解析它并将其略微更改为输出文件中定义的行号。
输入文件中的行格式如下:
linenumber:designator,"variable text content"
e.g。
3:string1,"this is text of string 1"
因此outfile在第3行应如下所示:
string1,"this is text of string 1"
该行包括双引号和空格。所有旧行都向下移动了一行。
用户有责任提供关于行顺序的正确输入文件,并且必须考虑输出文件中的每行在输入文件中的每一行都向下移动。除了输入文件中给出的行号之外,脚本不知道任何订单。
脚本应读取所有行并将这些行的内容放入给定行号
的输出文件中我与shell成功使用的命令是例如:
sed -i '3istring1,"this is text of string 1"' outfile
引号,双引号和空白没问题。 使用bash脚本
while read line
do
linenum=$(echo $line | cut -f1 -d:)
linestr=$(echo $line | cut -f2 -d:)
sedcmd="sed -i '"
sedcmd=${sedcmd}${linenum}
sedcmd=${sedcmd}i
sedcmd=${sedcmd}${linestr}
sedcmd=${sedcmd}"' outfile"
echo "---> $sedcmd"
$sedcmd
done < script/new_records.txt
显示与 echo 完全相同的 sed 命令,但返回:
sed: -e expression #1, char 1: unknown command: `''
显然在bash脚本中执行sed命令与直接在bash shell中执行它不同。 我尝试了各种转义序列&#34; \&#34;在引号,双引号和空白之前...而是随机的,并且这些都没有成功。
为了将包含空格和双引号的字符串写入文本文件中的指定行,我该怎么做?
答案 0 :(得分:1)
# Assuming OutFile exist and have enough line
while read ThisLine
do
LineNum=$(echo "${ThisLine}" | cut -f1 -d ":" )
echo "${ThisLine##*:}" > /tmp/LineContent.txt
sed -i -n "${LineNum} !{p;b;};r /tmp/LineContent.txt" OutFile
done < script/new_records.txt
不是最好的事情,因为你假设很多问题就像outfile中的足够的行一样,没有问题阅读该行(引用字符串中的转义字符怎么样,......)可能会发生
答案 1 :(得分:0)
好的,我会试一试。如果我了解您正在尝试正确执行的操作,并且您确定代码输入文件没有格式错误,那么
sed -i -f <(sed 's/:/i/' insertions.txt) datafile.txt
是最直接的方式。这是因为输入规范为
number:text
所有人必须要做的是用:
替换i
以获得一个sed命令:&#34;当处理行number
时,插入{{1 }}&#34 ;. text
位是bash样式的命令替换,扩展为FIFO的名称,从中可以读取命令的输出。
通过说出像
这样的话来防止错误可能是谨慎的<()
这将删除sed -i -f <(sed '/^[0-9]\+:/!d; s/:/i/' insertions.txt) datafile.txt
中所有不以数字开头后跟冒号的行,因为这些行显然已被破坏。
请注意,这种一体化方法会将行号视为输入文件中的行号。也就是说,给定带有内容的插入文件
insertions.txt
2:foo,"bar "
4:baz,"qux "
将出现在输出的第5行(输入的第4行之前)。如果不需要,则必须多次调用sed来单独处理每个插入,如
baz,"qux "
while read insertion; do
sed -i "${insertion/:/i}" datafile.txt
done < insertions.txt
是另一个基础,用${insertion/:/i}
替换shell变量中的第一个:
并扩展为结果,即i
,然后{{1} }是insertion=1:2:3
。