【问题标题】:Only print first and second word of each line to output with sed仅打印每行的第一个和第二个单词以使用 sed 输出
【发布时间】:2021-03-15 15:27:40
【问题描述】:

我想清理一个模式文件供以后使用,所以只有第一个和第二个单词(或数字)是相关的。

我有这个:

pattern.txt

# This is a test pattern
some_variable        one    # placeholder which replaces a variable
some_other_var 2    # other variable to replace
# Some random comment in between
different_var "hello"   # this will also replace a placeholder but with a string
    



# And after some empty lines:
  var_after_newlines        18          # some variable after a lot of newlines


{{hello}} " this is just a string surrounded by space "

{bello} "this is just a string"#and this is a comment

cello "#string with a comment in it"#and a comment

我申请的对象:

sed -nE '/^\s*#/d;/^\s*$/d;s/^\s*([^\s]+)\s+([^\s]+).*$/\1 \2/p' pattern.txt > output.txt

  • 它应该清除以 # 开头的注释行 -> 有效
  • 它应该清除空行(或带有空白字符的行)-> 有效
  • 它应该用由一 (1) 个空格字符分隔的第一个和第二个单词替换每一行 -> 不起作用。比较:

output.txt

期望:

some_variable one
some_other_var 2
different_var "hello"
var_after_newlines 18
{{hello}} " this is just a string surrounded by space "
{bello} "this is just a string"
cello "#string with a comment in it"

现实:

different_var "hello"   # thi
  var_after_newline
{{hello}} " thi
{bello} "thi
cello "#

我错过了什么?

编辑:

正如@Ed Morton 指出的那样,包括以下情况是有意义的:带空格的字符串、引号前后带空格的字符串、字符串中的 cmets 和引号之后的 cmets。接受的答案 sed 解决方案适用于所有这些。

【问题讨论】:

  • 如果一行只有1个“单词”应该打印什么?如果该行只是var # 1 word and a comment,应该打印什么?如果线路是var " string surrounded with space " 怎么办?如果是var "#string surrounded by#" 怎么办?请edit你的例子包括这些案例。

标签: awk sed


【解决方案1】:

完全基于您展示的示例,这可以通过awk 轻松完成。使用 GNU awk 编写和测试,应该适用于任何 awk

awk '{sub(/\r$/,"")} NF && !/^#/{print $1,$2}'  Input_file

解释:这里只检查两个条件。 1st-NF 确保行不是空行。第二行不以 # 开头,然后打印当前行的第一列和第二列。



使用sed请尝试在 GNU 中关注 sed

sed -E 's/\r$//;/^#/d;/^\s*$/d;s/^ +//;s/([^ ]*) +([^ ]*).*/\1 \2/' Input_file

或者根据 Ed sir 的 cmets 使用以下内容:

sed -E 's/\r$//; /^#/d; /^\s*$/d; s/^\s+//; s/(\S*)\s+(\S*).*/\1 \2/' Input_file

上述两种解决方案的示例输出如下:

some_variable one
some_other_var 2
different_var "hello"
var_after_newlines 18

【讨论】:

  • 这工作完美无缺,谢谢。我一直在努力理解 sed。你知道使用 sed 会是什么样子吗?
  • @glades,当然,请尝试使用 GNU sed 关注一次:sed -E '/^#/d;/^\s*$/d;s/^ +//;s/([^ ]*) +([^ ]*).*/\1 \2/' Input_file,如果这对您有帮助,请告诉我。
  • 这并不能很好地完成工作。它仍然包含“#”和制表符
  • @glades,对我来说,sedawk 解决方案都运行良好,并且老实说给出了相同的结果。
  • 有趣。你用的是linux吗?我在 Windows 上使用 git bash,也许这就是区别。例如,对于我得到的第一行:some_variable one,它仍然包含一个制表符和空格第二行给出:some_other_var 2 #
【解决方案2】:

在 GNU 中 sed

sed -E '/^\s*(#.*)?$/d; s/^\s*(\S+)\s+(\S+).*/\1 \2/' pattern.txt

在 cmets 之后更新:

sed -E '/^\s*(#.*)?$/d; s/^\s*(\S+)\s+("[^"]*"|\S+).*/\1 \2/' pattern.txt

【讨论】:

  • 这行得通,谢谢!我刚刚检查了它是否也适用于我想要替换的整个字符串替换:{{hello}}“它有效,你好世界!”但这只会将"it 放在相应的位置。有没有简单的解决方法?
  • @glades 我没有完全理解。是否可以给出示例行和预期输出?
  • 当然,输入类似于{{hello}} "this is just a string" # some string,它由两列 {{hello}} 和“这只是一个字符串”组成。预期的输出将是 {{hello}} "this is just a string" 并删除了注释,但请注意,字符串位由当前解决方案的空格分隔,这是一个问题。
【解决方案3】:

应该适用于大多数 sed 的版本:

$ sed 's/^[[:space:]]*//; s/#.*//; /^$/d; s/^\([^[:space:]]\{1,\}\)[[:space:]]\{1,\}\([^[:space:]]\{1,\}\).*/\1 \2/' pattern.txt
some_variable one
some_other_var 2
different_var "hello"
var_after_newlines 18

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-26
    • 2015-07-16
    • 1970-01-01
    • 2011-10-11
    • 2017-12-06
    • 1970-01-01
    相关资源
    最近更新 更多