bash 脚本:将带双引号和空格的字符串写入文件

bash script: write string with double quotes and blanks to file

我尝试使用 sed 从 ASCII 文件中读取一行,解析它并将其写入输出文件中定义的行号。

输入文件中的行格式如下:

linenumber:designator,"variable text content"

例如

3:string1,"this is text of string 1"

因此输出文件在第 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

显示完全相同的 sed 命令与 echo 但 returns 与:

sed: -e expression #1, char 1: unknown command: `''

显然,从 bash 脚本中执行 sed 命令不同于直接在 bash shell 中执行。 我在引号、双引号和空格之前尝试了各种转义序列“\”……但是是随机的,但都没有成功。

如何将包含空格和双引号的字符串写入文本文件的指定行?

# 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 中有足够的行,读取该行没有问题(引号字符串中的转义字符,...)可能会发生

好的,我试试看。如果我理解您要正确执行的操作,并且您确定代码输入文件没有格式错误,那么

sed -i -f <(sed 's/:/i/' insertions.txt) datafile.txt

是最直接的方法。这是有效的,因为输入规范为

number:text

所有需要做的就是将 : 替换为 i 以获得一个 sed 命令:"When handling line number, insert text"。 <() 位是 bash 样式的命令替换,它扩展为可以从中读取命令输出的 FIFO 的名称。

为了防止错误,可以这样说

sed -i -f <(sed '/^[0-9]\+:/!d; s/:/i/' insertions.txt) datafile.txt

这会删除 insertions.txt 中所有不以数字后跟冒号开头的行,因为这些行显然已损坏。

请注意,这种一体式方法将行号视为输入文件中的行号。也就是说,给定一个包含 content

的插入文件
2:foo,"bar "
4:baz,"qux "

baz,"qux " 将出现在输出的第 5 行(输入的第 4 行之前)。如果不需要,则必须多次调用 sed 以单独处理每个插入,如

while read insertion; do
  sed -i "${insertion/:/i}" datafile.txt
done < insertions.txt

${insertion/:/i} 是另一种 bashism,它将 shell 变量中的第一个 : 替换为 i 并扩展为结果,即,如果insertion=1:2:3,那么${insertion/:/i}就是1i2:3.