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
.
我尝试使用 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
.