【问题标题】:using sed and awk to copy file name into a file使用 sed 和 awk 将文件名复制到文件中
【发布时间】:2018-10-20 04:48:15
【问题描述】:

我最近添加了一个question here,关于如何使用 sed 和 awk 在文件中获取文本字符串并使用它来命名文件。现在我试图弄清楚如何反过来 - 使用文件名,并将该文本插入到文件中的指定点。

使用相同的文本示例,假设此文件名为 test1.Rnw

\begin{question}


A business incurs the following costs per unit: Labor  \$125/unit; Materials \$45/unit and rent  \$250,000/month. If the firm produces 1,000,000 units a month, the total variable costs equal
\begin{answerlist} 
\item \$125Million

\item \$45Million

\item \$1Million

\item \$170Million


\end{answerlist}
\end{question}

\begin{solution}
\begin{answerlist}
\item F. 
\item F. 
\item F. 
\item F. 
\end{answerlist}
\end{solution}

\exname{target}
\extype{schoice}
\exsolution{0001}
\exshuffle{TRUE}

我现在想取文件名test1.Rnw 并将该文本插入该文件中的\exname{target} 位置,替换文本target。最好在此处插入 test1不是 .Rnw 扩展名。

我希望我可以使用我的prior question(以及非常好的回复)来制定解决方案,但我被卡住了。

=======

【问题讨论】:

  • 结果应该是\exname{test1}吧?
  • Allan,你说得对,结果应该是这样的,从 \exname{target} 到 \exname{test1}。文件的其余部分(包括文件名)应保持不变。
  • 您能否检查我的 2 个解决方案(sedawk)并告诉我它是否适合您?谢谢!另请注意,在我的示例中,文件扩展名是rnwr 小写。
  • 他们确实有效,非常感谢您的帮助,艾伦!
  • 给新人的建议:如果一个答案解决了您的问题,请点击旁边的大复选标记 (✓) 接受它,也可以选择投票(投票至少需要 15 声望)点)。如果您发现其他答案有帮助,请给他们投票。接受和投票有助于未来的读者。请看【相关帮助中心文章】[1] [1]:stackoverflow.com/help/someone-answers

标签: macos awk sed


【解决方案1】:

您有不同的工作方式,我建议您使用sed,因为您想替换文件中的某些模式。

输入:

$ cat test1.rnw

\begin{question}


A business incurs the following costs per unit: Labor  \$125/unit; Materials \$45/unit and rent  \$250,000/month. If the firm produces 1,000,000 units a month, the total variable costs equal
\begin{answerlist} 
\item \$125Million

\item \$45Million

\item \$1Million

\item \$170Million


\end{answerlist}
\end{question}

\begin{solution}
\begin{answerlist}
\item F. 
\item F. 
\item F. 
\item F. 
\end{answerlist}
\end{solution}

\exname{target}
\extype{schoice}
\exsolution{0001}
\exshuffle{TRUE}

命令:

FILENAME=`basename test1.rnw .rnw`; sed 's/^\\exname{target}/\\exname{'"$FILENAME"'}/' test1.rnw

说明:

  • basename 命令与文件名和扩展名一起使用以将其从文件名中删除,结果存储在名为FILENAME 的变量中。
  • 您使用sedfind and replace 功能并替换^\\exname{target}(以\exname{target} 开头的行由\exname{ 后跟FILENAME 变量的内容并以} 结尾

输出:

\begin{question}


A business incurs the following costs per unit: Labor  \$125/unit; Materials \$45/unit and rent  \$250,000/month. If the firm produces 1,000,000 units a month, the total variable costs equal
\begin{answerlist} 
\item \$125Million

\item \$45Million

\item \$1Million

\item \$170Million


\end{answerlist}
\end{question}

\begin{solution}
\begin{answerlist}
\item F. 
\item F. 
\item F. 
\item F. 
\end{answerlist}
\end{solution}

\exname{test1}
\extype{schoice}
\exsolution{0001}
\exshuffle{TRUE}

待办事项:

  • 将标准输出重定向到文件以保存结果
  • 或使用-i-i.bak 就地进行更改(请先备份)

文档:

https://www.gnu.org/software/sed/manual/sed.html

如果您是awk 的爱好者,您还可以使用以下命令来达到相同的结果:

awk '/^\\exname/{noext=FILENAME;sub(/\..*$/,"",noext);print "\\exname{"noext"}";next}1{print}' test1.rnw

说明:

  • 1{print} 将打印每一行
  • /^\\exname/{noext=FILENAME;sub(/\..*$/,"",noext);print "\\exname{"noext"}";next} 对于以 \exname 开头的行,您访问 FILENAME 并使用 noext=FILENAME;sub(/\..*$/,"",noext) 删除扩展名,然后使用 print "\\exname{"noext"}" 打印该行并转到 next 行以避免重复打印。

【讨论】:

  • 谢谢,艾伦,我已经尝试过这些,它似乎工作得很好。现在,我试图弄清楚如何在目录中的一堆文件上循环它。我认为我可以修改您在此处发布的代码,但问题是文件名似乎是硬编码的。有没有办法将它定义为一个变量,这样我就可以在一个充满 .Rnw 文件的目录中循环它?
  • 当文件名包含反向引用元字符(例如 &\<number>)时,sed 脚本将失败。在 awk 命令中x{print "\\exname{"noext"}";next}1{print} = x{$0="\\exname{"noext"}"}1
【解决方案2】:

鉴于\exname{target} 中的target 是您感兴趣的内容:

1) 根据target的值命名文件:

awk -F'[{}]' 'NR==FNR{if ($1=="\\exname") fname=$2; next} {print > fname}' file file

2) 用当前文件名替换target

awk -F'[{}]' '$1=="\\exname"{ $0 = $1 "{" FILENAME "}" } 1' file

您不需要 shell lop 来操作多个文件,但在这种情况下它确实具有简单、吸引人的一致语法:

for file in *; do
   awk as above but replace `file` with `"$file"`
done

如果你想用 awk 命令的输出替换原始文件:

for file in *; do
   awk -F'[{}]' 'NR==FNR{if ($1=="\\exname") fname=$2; next} {print > fname}' "$file" "$file" &&
   rm -f "$file"
done

for file in *; do
   awk -F'[{}]' '$1=="\\exname"{ $0 = $1 "{" FILENAME "}" } 1' "$file" > tmp &&
   mv tmp "$file"
done

【讨论】:

  • @exl 是什么让您改变主意并取消选择此作为接受的答案?毕竟,它是您获得的最强大、最便携、最灵活和最完整的答案。
猜你喜欢
  • 2014-02-17
  • 1970-01-01
  • 1970-01-01
  • 2015-05-06
  • 2019-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-10
相关资源
最近更新 更多