Bash 脚本用于打印具有一定行长度的文件

Bash 脚本用于打印具有一定行长度的文件

我是新手...我需要一个脚本,它接收一个目录作为参数并打印出 15 到 50 行之间的文件的名称,但我不知道如何wcif句子中使用输出:

#!/bin/bash
for f in `ls`; do
  echo "File -> $f"
  cat $f | wc -l
done

我如何接收参数?如何将输出分配wc给变量?

答案1

参数可以作为$1$2等来接收,或者$*全部接收。

还有数组$@,通常用作"$@"的更好版本$*。另一种可能的用法是${@:3}表示“从第 3 个开始的所有参数”。

要获取命令的输出,请使用$( ... )或其旧形式` ... `。通常建议总是使用,$()因为它可以嵌套,例如blah=$(cat /blah/$(blah)/blah)

#!/usr/bin/env bash

for dir in "$@"; do
    for file in "$dir"/*; do
        lines=$(wc -l < "$file")
        if (( lines >= 15 && lines <= 50 )); then
            echo "File -> $file ($lines lines)"
        fi
        # another possible syntax:
        # if [ "$lines" -ge 15 ] && [ "$lines" -le 50 ]
        # or:
        # if [[ "$lines" -ge 15 && "$lines" -le 50 ]]
    done
done

有用的资源:

答案2

下面是另一种使用方法awk

#!/usr/bin/env bash
for dir in "$@"; do
  for file in "$dir"/*; do 
    awk 'END{if(NR>=15 && NR<=50){print FILENAME}}' "$file"; 
  done
done

说明:(awk及其许多变体,如gawkmawk等)逐行读取文件。变量NR是当前行号。END{}当到达输入文件的最后一行时,将执行一个块,此时NR将是文件中的行数。最后,FILENAME是当前正在处理的文件的名称。因此,如果脚本看到的行数在 15 到 50 之间,它将打印文件的名称。

类似地,你可以用 Perl 来做到这一点:

#!/usr/bin/env bash
for dir in "$@"; do
  for file in "$dir"/*; do 
      perl -ne 'END{if($. >=15 && $. <=50){print "$ARGV\n"}}' "$file"
  done
done

说明:perl -ne还将逐行读取文件。在 Perl 中,当前行号存储在中$.END块的工作方式与 中相同awk$ARGV是在命令行上传递的参数,文件名只有在行数正确时才会打印。

你最好的选择可能是 bash 和wc 回答@grawity 但这些不会受到wc实现的影响并且应该可以在任何 *nix 上很好地运行。

答案3

生成一些文件:

$ for i in `seq -w 1 60`; do seq -w 1 $i > $i.lines; done

仅打印符合条件的:

$ wc -l * | awk '$1 >= 15 && $1 <= 50 { print $2 }' | column
15.lines        23.lines        31.lines        39.lines        47.lines
16.lines        24.lines        32.lines        40.lines        48.lines
17.lines        25.lines        33.lines        41.lines        49.lines
18.lines        26.lines        34.lines        42.lines        50.lines
19.lines        27.lines        35.lines        43.lines
20.lines        28.lines        36.lines        44.lines
21.lines        29.lines        37.lines        45.lines
22.lines        30.lines        38.lines        46.lines

相关内容