代码之家  ›  专栏  ›  技术社区  ›  exl

使用sed和awk将文件名复制到文件中

  •  2
  • exl  · 技术社区  · 7 年前

    我最近添加了 question here 介绍如何使用sed和awk在文件中获取文本字符串并使用它命名文件。现在,我正试图找出如何反转-使用文件名,并在指定点将该文本插入到文件中。

    使用相同的文本示例,假设此文件被调用 测试1。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 (以及非常好的回答)来解决问题,但我被卡住了。

    =======

    2 回复  |  直到 7 年前
        1
  •  1
  •   Ed Morton    7 年前

    鉴于 target 在里面 \exname{target} 是您感兴趣的:

    1) 根据的值命名文件 目标 :

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

    2) 替换 目标 使用当前文件名:

    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
    
        2
  •  0
  •   Allan    7 年前

    你有不同的工作方式,我建议使用 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
    • 您使用 find and replace 的特征 sed公司 和替换 ^\\exname{target} (以开头的行 \exname{target} 通过 \exname{ 其次是 文件名 变量和结束方式 }

    输出:

    \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 lover您也可以使用以下命令获得相同的结果:

    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 使用访问文件名并删除扩展名 noext=FILENAME;sub(/\..*$/,"",noext) ,然后使用 print "\\exname{"noext"}" 然后去 next 避免重复打印。