【问题标题】:Removing line form file containing $A but not $B从包含 $A 但不包含 $B 的文件中删除行
【发布时间】:2018-07-12 09:03:56
【问题描述】:

我想从文本文件中删除所有行

  • 包含变量$A
  • 但如果它也包含变量 $B 则不是

目前我有类似的东西:

sed -e '/${VAR_A_TO_BE_DELETED}/ {/${VAR_B_DONT_DELETE}/! s/$VAR_A_TO_BE_DELETED/STRING_TO_MARK_DELETION/}' $FILE_NAME | grep -v STRING_TO_MARK_DELETION > temp_file; mv temp_file $FILE_NAME

有没有更优雅的方式?这似乎并不总是有效(仍然必须弄清楚“不工作”的参数是什么)。

【问题讨论】:

  • 什么时候不工作?当你有两个 $A 实例就行了?您忘记了s/// 末尾的g。它几乎和它一样好。您可以使用n; 代替!
  • 我很困惑。您是否尝试匹配名为$VAR_A_TO_BE_DELETED 的变量中的文本?如果是这样,您使用了错误的引号,并且 shell 没有插入该变量。如果您正在寻找文字文本${VAR_A_TO_BE_DELETED},那么我不明白为什么s/// 命令中缺少大括号。请编辑问题以确保准确性。

标签: bash sed


【解决方案1】:

使用 sed+grep 执行您当前尝试执行的操作的更优雅的方法是使用 awk:

awk -v a="$VAR_A_TO_BE_DELETED" -v b="$VAR_B_DONT_DELETE" '
    ($0 ~ b) || !($0 ~ a)
' "$FILE_NAME" > temp_file && 
mv temp_file "$FILE_NAME"

而且,由于您有时说这不起作用并且猜测这是由于变量内容中的正则表达式元字符,所以正确的方法是使用字符串操作而不是正则表达式:

awk -v a="$VAR_A_TO_BE_DELETED" -v b="$VAR_B_DONT_DELETE" '
    index($0,b) || !index($0,a)
' "$FILE_NAME" > temp_file && 
mv temp_file "$FILE_NAME"

如果您的变量可以包含反斜杠,例如\t 然后上面将扩展它们,例如到一个制表符。如果这是一个问题,那么您可以在变量赋值中的每个反斜杠之前添加一个反斜杠,或者这样做:

awk '
    BEGIN {
        a=ARGV[2]; ARGV[2]=""; ARGC--
        b=ARGV[3]; ARGV[3]=""; ARGC--
    }
    index($0,b) || !index($0,a)
' "$FILE_NAME" "$VAR_A_TO_BE_DELETED" "$VAR_B_DONT_DELETE" > temp_file && 
mv temp_file "$FILE_NAME"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多