【问题标题】:Bash, sed/awk/grep filework removing specific rowsBash、sed/awk/grep 文件删除特定行
【发布时间】:2018-08-25 23:50:43
【问题描述】:

我想查找并删除特定行,但它只能部分工作

我的文件:(文件名、日期、计数、文件路径)

test1.txt;2018-03-16;2;/path/to/file1
test2;2018-03-16;2;/path/to/file1
test3.txt;2018-03-16;2;/path/to/file2

脚本参数:

  • $1 = 目录(最后一列)
  • $2 = 文件名(第一列)

我的目标:

  • A) 我想保存以 $2 结尾的列的文件名并将它们写出来
  • B) 我想用 Given $1 和 $2 参数删除整行

到目前为止我得到了什么:

#This only gets the last part of path/to/file -> 'file' in this case
EndOfDirPath=`echo "$1" | sed 's/\(^.*\)\/\(.*\)/\2/'`
#This removes the files starting with the inputed filename and last part of #directory
sed -i '/^'$2'.*'$EndOfDirPath'$/d' file

我想要它做什么:

$ foo test2 /path/to/file1
test1.txt
test2

文件应该是这样的:

test1.txt;2018-03-16;2;/path/to/file1
test3.txt;2018-03-16;2;/path/to/file2

任何提示都会有所帮助!

【问题讨论】:

  • 即使您的论点是/path/to/file1,为什么还要在输出中期待test3.txt;2018-03-16;2;/path/to/file2??
  • 这不是输出,这只是使用文件参数运行所需脚本后的文件。 foo(name of the script) test2 (-> $1) /path/to/file1(->$2) 当我运行脚本时我想在标准输出上写入与 $2 具有相同路径的文件名而不是我想删除 $1 (test2) 如果它也有相同的 $2(Path) 否则文件保持不变

标签: bash shell sed


【解决方案1】:

我怀疑你的代码和调用之间的参数顺序被交换了?我假设第一个字段(文件名)是第一个字段,最后一个字段(目录)是第二个字段,您只需要最后一部分(基本文件名)。

还应该注意sed 可能不是在这里使用的最简单的选择。您正在寻找的是就地处理文件,同时还在控制台上发出一些东西。额外的p 命令最终会出现在您正在处理的同一流/文件中。 w/dev/stdout 似乎不支持使用 write。当然可以通过两次 sed 来完成。或者完全使用不同的工具(可能是 Python 或 Perl 脚本)。

您也可以反过来,一路打印,而不是将结果写入新文件,但我确实找到了一种使用sed(一次)并且不需要额外文件的方法。对于sed 的单次传递,我得到了以下信息(不涉及安全临时文件的创建和清理):

sed -i '/\<'"$(basename $2)"'$/{
        h
        s/;.*//
        w tempfile
        x
    }
    /^'$1'.*\<'"$(basename $2)"'$/d' file
cat tempfile

它有什么作用?在第一个块中,我采用以第二个参数的基本名称(路径的最后一部分)结尾的每一行。我将它保存到保持空间h 中(这样我可以切一些位,但以后仍然有完整的行)。然后我删除第一个分号 (;) 之后的所有内容。将其写入 (w) 到名为 tempfile 的文件中。并将模式空间与保持空间交换,从而恢复原始行 (x)。在第二个区块中,我执行与您之前相同的操作。删除以第一个参数开始并以第二个参数的最后一个路径组件结束的所有行。

请注意,对于第二个参数匹配,我在它前面加上了\&lt;,以确保/path/to/file1 最终不会匹配/path/to/xfile1,否则会出现这种情况。如果您想保留整个路径,则需要使用不同的字符,因为路径中的斜杠会扰乱sed,例如,您可以说:'\#'"$2"'#'

为了完整起见,两个pass选项:

sed -ne '/\<'"$(basename $2)"'$/s/;.*//p' file
sed -i '/^'$1'.*\<'"$(basename $2)"'$/d' file

说了这么多。仍然可能最好不要使用sed 执行此特定任务。 ;)

【讨论】:

    最近更新 更多