【问题标题】:Shell Script (awk)外壳脚本 (awk)
【发布时间】:2015-09-16 02:48:56
【问题描述】:

如何使用 unix shell 脚本 awk 从文本文件中提取一些行。

例如 1) 输入:file_name_test.txt

**<header> asdfdsafdsf**  
11 asd sad
12 sadf asdf
13 asdfsa asdf
14 asd sdaf
**15 asd asdfsdf
16 sadfsadfsaf sdfsdf
17 asdf sdaf
18 asfd saf
19 sadf asdf
10 asf asf**

2) 预期输出:

**<header> asdfdsafdsf
15 asd asdfsdf
16 sadfsadfsaf sdfsdf
17 asdf sdaf
18 asfd saf
19 sadf asdf
10 asf asf**

3) test.sh 的代码:

FILENAME=$1
threshold=$2
awk '{line_count++;
if (line_count==1 || (line_count>$threshold))
print $0;
}' $FILENAME > overflow_new2

4)

sh test.sh file_name_test.txt 5

5) 它只打印第一行:

<header> asdfdsafdsf

在输出文件overflow_new2.并在腻子中返回这些行:

awk: Field $() is not correct.
The input line number is 2. The file is file_name_test.txt
The source line number is 2.

有什么想法吗?谢谢。

【问题讨论】:

  • 能否先通过脚本明确说明你想做什么?

标签: shell unix awk


【解决方案1】:

让我先修复你的脚本:

#!/bin/bash
FILENAME=$1
THRESHOLD=$2

awk -v t=$THRESHOLD '{
        lc++;
        if (lc == 1 || lc > t) {
                print $0;
        }
}' $FILENAME

【讨论】:

  • 你甚至不需要lc 变量:awk -v t=$THRESHOLD 'NR==1 || NR&gt;t' $FILENAME
【解决方案2】:

您需要使用-v 标志将shell 变量传递给awk

filename=$1
threshold=$2

awk -v thres="$threshold" '
    { line_count++ }
    line_count==1 || line_count > thres { print }
' $filename > overflow_new2

当运行时:

./script.sh file_name_test.txt 5

overflow_new2的结果/内容:

**<header> asdfdsafdsf**  
**15 asd asdfsdf
16 sadfsadfsaf sdfsdf
17 asdf sdaf
18 asfd saf
19 sadf asdf
10 asf asf**

另外,为了准确再现所需的结果,我会这样做:

filename=$1
threshold=$2

awk -v thres="$threshold" '
    FNR == 1 {
        sub(/**\s*$/,"")
        print
    }
    FNR > thres {
        sub(/^**/,"")
        print
    }
' $filename > overflow_new2

【讨论】:

  • 谢谢史蒂夫不知道我们需要-v。顺便说一句,是否需要 {print $0} 而不是 {print}?为什么 thres="$threshold" 阈值作为字符串传递?如果我需要 thres 来做附加条件,例如: awk -v thres="$threshold" ' { line_count++ } line_count==1 || line_count > thres+thres { print } ' $filename > overflow_new2
  • 默认情况下,awk 打印整行 ($0),因此您可以简单地编写 print。这同样适用于其他命令,如 sub() 函数。我不确定我是否理解您的第二个请求,但您可以使用 -v 标志将多个 shell 变量传递给 awk。你给出的命令也应该如你所愿。
  • 得到了 0 美元,谢谢。我可以用 thres 变量进行算术运算吗?因为条件是“line_count==1 || line_count > thres+thres”而不是“line_count==1 || line_count > thres”
  • 感谢史蒂夫,工作就像一个魅力。你让我今天一整天都感觉很好。太感谢了。 awk -v thres="$threshold" ' { line_count++ } line_count==1 || ((line_count > thres) && (line_count overflow_new
【解决方案3】:

这是类似于 glenn jackman 的解决方案的 Perl 代码:

perl -slne 'print if $. == 1 or $. >= $n' -- -n=15 

$.是行号

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多