从for模式到for循环中的文件结尾

时间:2015-03-25 12:05:39

标签: bash for-loop sed

我正在编写一个bash脚本,允许我从文件中获取一定数量的文本,并在此之前添加一些其他文本以获取文件列表。

directory=$(pwd)

    for f in *test.txt
    do


        filename=$(basename $f .txt)

        printf "%%sum=4 \n"> input.temp
        printf "file=$directory"/"$filename".txt" \n">> input.temp

        printf "some commands \n">> input.temp

        printf "\n" >> input.temp
        printf "description \n">> input.temp

        sed -n "/0 1/,$p" "$f" >> input.temp;


mv input.temp $filename.temp
done

我在for循环中遇到了sed命令的问题。我环顾四周,人们建议添加双引号,我做了但无济于事。我想这可能是$ p。 我希望这很清楚。如果不是,我会尝试更好地解释。

sed -n "/0 1/,$p" "$f" >> input.temp;不起作用

sed -n '/0 1/,$p' "$f" >> input.temp;不起作用

sed -n "/0 1/,\$p" "$f" >> input.temp;不起作用

仅供参考我不是想找到其他有用的东西。我想修复这个确切的输入。我听起来像个混蛋。

示例输入

%sum=8
file=otherpath/filename.txt
some other commands

another description

0 1

                       0.36920852   -0.56246512    
                       0.77541848    0.05756533    
                       2.05409026    0.62333039    
                       2.92655258    0.56906375    
                       2.52034254   -0.05096652    
                       1.24167014   -0.61673008    
                      -0.60708600   -0.99443872    
                       0.10927459    0.09899803    
                       3.90284624    1.00103940    
                       3.18648588   -0.09239788    
                       0.93151968   -1.09013674    
                       2.50047427    1.30468389    
                       2.19361322    2.54108378   
                       3.18742399    0.34152442   
                       3.38679424    1.11276220   
                       1.56936488    3.27250306    
                       1.81754180    4.19564055    

     1 2 1.5 6
     2 3 1.5 
     3 4 
     4 5 1.5
     5 6 1.5 
     6 11 1.0
     7
     8
     9
     10
     11
     12
     13 16
     14 
     15
     16 17
     17

我想要的输出基本上是这个文件从“0 1”到结尾之前我放在printf中的东西。

更新:如果你有兴趣,两个脚本tripleee和Ed Morton提供的工作非常好。我的脚本中的问题是我从sed行(forplace)中省略了-i选项。

sed -n "/0 1/,$p" "$f" >> input.temp

应替换为

sed -ni '/0 1/,$p' "$f"

2 个答案:

答案 0 :(得分:1)

就像其他人已经评论过的那样,你基本上只需要使用单引号而不是double,因为在{引用$p之前,shell引用了shell变量p的值{ {1}}执行(实际上,可能是一个空字符串)。

但是,您可能还想调查sed中的所有内容。然后你可能会坚持使用双引号(因为你还想要替换其他变量),而是使用反斜杠转义sed中的美元符号以保护它不受shell的影响。

$p

在实践中,我想你希望输出文件在每次迭代中都是不同的(可能是directory=$(pwd) # just do this once before the loop; the value doesn't change for f in *text.txt; do # no braces filename=$(basename "$f" .txt) sed -n "1i\\ %sum=4\\ file=$directory/$filename.txt\\ some commands\\ \\ description /0 1/,\$p" "$f" >inputout.temp2 # no pointless separate temp file done 而不是?)但是你做的事情显然取决于你。就像现在一样,该文件将包含上次迭代的输出。

答案 1 :(得分:1)

我看到你更新了你的问题,并在评论中提供了一些额外的信息,所以试试这个,使用GNU awk 4. * for -i inplace

awk -i inplace -v directory="$(pwd)" '
FNR==1 {
    print "%%sum=4 "
    print "file=" directory "/" FILENAME
    print "some commands "
    print ""
    print "description "
    found = 0
}
/0 1/ { found = 1 }
found
' *text.txt

如果你没有GNU awk,那么技术上正确的方法就是使用xargs但是使用shell循环来处理文件操作(移动)部分更简单:

for file in *test.txt
do
    awk -v directory="$(pwd)" '
    FNR==1 {
        print "%%sum=4 "
        print "file=" directory "/" FILENAME
        print "some commands "
        print ""
        print "description "
        found = 0
    }
    /0 1/ { found = 1 }
    found
    ' "$file" > tmp && mv tmp "$file"
done