0

在 bash 脚本中,我想循环一个数组并每次执行一个 sed 命令。基本上,我想做这样的事情:

名称=(“彼得”“胡安卡洛斯”“艾米丽”)  

${names[*]} 中的名称     
做    
  sed 's/[[:space:]]*{'"$name"'}/'"$name"'/g' "$file"
完毕

我想念什么?

编辑:我进一步解释我的意图:

我的来源是一个 tex 文档,其中包含以下行:

\begin{cue}
    {Peter}           
    {You won !}
\end{cue}
\begin{cue}
    {Juan Carlos}           
    {Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vitae ipsum hendrerit, gravida est eget, tincidunt sem. Maecenas dapibus nibh commodo, pulvinar lorem at, egestas leo.}
\end{cue}

很好,我想要一个 .csv 文档,格式如下

“彼得”;“你赢了!
“Juan Carlos”;“Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vitae ipsum hendrerit, gravida est eget, tincidunt sem. Maecenas dapibus nibh commodo, pulvinar lorem at, egestas leo。”

感谢您的回答!

4

3 回答 3

1

我不完全确定您在做什么,但一些诊断信息可能会对您有所帮助。如果我尝试脚本:

names=( "Peter" "Juan Carlos" "Emily")
file=test.txt

for name in ${names[*]}     
do    
  echo ">>" $name
  sed 's/[[:space:]]*{'"$name"'}/'"$name"'/g' "$file"
done

...在文件上test.txt

    Peter
Carlos
Simon

...我得到输出:

>> Peter
    Peter
Carlos
Simon
>> Juan
    Peter
Carlos
Simon
>> Carlos
    Peter
Carlos
Simon
>> Emily
    Peter
Carlos
Simon

...这表明脚本为names. 那是你的意图吗?

我猜你可能正在寻找的是:

names=( "Peter|Juan Carlos|Emily")
file=test.txt
IFS="|"
for name in ${names[*]}     
do    
  echo ">>"  $name
  sed -e"s/[[:space:]]*$name/$name/g" "$file"
done

...它给出的输出如下:

>> Peter
Peter
Carlos
Simon
>> Juan Carlos
    Peter
Carlos
Simon
>> Emily
    Peter
Carlos
Simon

... 即,如果在输入文件中找到该名称,则循环的名称将删除其前面的空格。

于 2013-09-01T07:17:39.130 回答
1

也许这就是你真正打算做的:

#!/bin/bash

names=("Peter" "Juan Carlos" "Emily")
file="<your file's path here>"

expressions=()
template='s|[[:space:]]*{__NAME__}|__NAME__|g'

for __ in "${names[@]}"; do
    expressions+=(-e "${template//__NAME__/$__}")
done

sed "${expressions[@]}" -- "$file"  ## or sed -i ... to replace contents of file

运行bash script.sh

于 2013-09-01T08:17:56.037 回答
0

虽然您的问题是合法的,但遍历演员姓名是解决您陈述的问题的一种极其低效的方法。也许接受一个可以解决您最初问题的答案,但然后从这样的事情重新开始。

awk -F '[{}]' '/^\\begin\{cue\}$/ { i=0;next }                                 
   ++i == 1 { actor=$2; next }                                                  
   i == 2 { printf "\"%s\";\"%s\"\n", actor, $2; next }' "$file"

这将在花括号上分割每一行输入,并计算每一行相对于前一个实例的索引\begin{cue}。如果是一个,则保存第二个字段以备后用。如果是两个,则打印保存的值和当前行的第二个字段。

sed相同的逻辑可以在sed.

如果您的输入文件比您的示例让我们理解的更复杂,您可能希望转向更高级别的语言,例如 Python 或 Perl,并为其编写适当的解析器。使用正确的库,它不必比这个 Awk 示例复杂得多。

于 2013-09-01T12:14:17.783 回答