【问题标题】:How can I remove lines from .txt files using a loop?如何使用循环从 .txt 文件中删除行?
【发布时间】:2012-07-20 16:27:27
【问题描述】:

在我的当前目录中,我有几个 .txt 文件。我想编写一个脚本来搜索这些 .txt 文件中的字符串,并删除包含该字符串的行。 例如,我想删除当前目录下所有 .txt 文件中所有带有“start”字样的行。

我已经写了以下代码,但是我不知道如何继续!

#!bin\bash
files=`find . -maxdepth 1 -name \*.txt`

我应该如何使用“while”来遍历每个文件?

【问题讨论】:

    标签: file bash loops edit


    【解决方案1】:

    在将find 的结果传递给它之后,您可以使用它along with read 依次获取每个文件名。然后您只需将文件名传递给sed 即可删除您感兴趣的行。

    【讨论】:

    • 你的意思是这样的 find 。 -maxdepth 1 -name *.txt | read 但是如何到达 read 的每个条目呢?可以多解释一下吗?
    • "我应该如何使用"while"来遍历每个文件?"阅读链接。
    【解决方案2】:

    简单易行: sed -i "s/^.*string.*//" *.txt 这将删除每个 .txt 文件中包含“字符串”的任何行

    【讨论】:

    • a.) -i 需要一个参数(用于备份扩展),如果不需要备份,则为空,例如 -i "" 。 b.) s/.*someting.*// not 删除该行,仅将其替换为空行。所以它很容易,但不是你的解决方案,而是: sed -i "" "/string/d" *.txt
    • 您确定替换而不是删除是正确的,但不确定您对 -i 选项的含义。如果 -i 为空,sed -i "s/string/d" *.txt 可以正常工作,不需要 -i 之后的额外 ""
    • 仅在 gnu-sed 上。便携式 sed 必须有空字符串 "" 用于无需备份的简单覆盖...
    【解决方案3】:

    使用 Glob 填充循环变量

    当您在当前目录上使用-maxdepth 1 时,您不会递归到子目录。如果是这样的话,完全没有必要使用 find 来匹配带有扩展名的文件;你可以使用shell globs 来填充你的循环结构。例如:

    #!/bin/bash
    
    # Run sed on each file to delete the line.
    for file in *txt; do
        sed -i '/text to match/d' "$file"
    done
    

    这很简单,并且避免了在进程之间传递文件名参数时可能遇到的许多与文件名相关的问题。保持简单!

    【讨论】:

    • 或者简单地说:sed -i '/text to match/d' *.txt(用于 gnu-sed)。或 sed -i "" '/text/d' *.txt 用于便携式 sed。对于递归(bash4) sed -i '/text/d' **/*.txt (KISS)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-13
    • 1970-01-01
    相关资源
    最近更新 更多