1.如何使用不包括第一个2.Using的输入grep和sed找到用户输入的模式以及如何创建下一行

1. How to use the input not including the first one 2.Using grep and sed to find the pattern entered by the user and how to create the next line

我正在执行的命令希望第一个输入是一个文件,并使用 grep 和 sed 搜索特定模式在文件中出现的次数。 例如:

$ cat file1
oneonetwotwotwothreefourfive

预期输出:

$ ./command file1 one two three
one 2
two 3
three 1

问题是文件没有任何行,只是一长串字母。我正在尝试使用 sed 将我正在寻找的模式替换为“FIND”并将列表移至下一行,这一直持续到文件末尾。然后,使用 $grep FIND 获取包含 FIND 的行。最后,使用 wc -l 查找一些行。但是,我找不到将列表移动到下一行的选项

例如:

$cat file1
oneonetwosixone

预期输出:

FIND
FIND
twosixFIND

我遇到的另一个问题是如何使用其余输入,不包括文件。

尝试失败:

file=
for PATTERN in 2 3 4 5 ... N
do
variable=$(sed 's/$PATTERN/find/g' $file | grep FIND $file | wc -l)
echo $PATTERN $variable
exit

又一次失败的尝试:

file=
PATTERN=$(, ... $N)
for PATTERN in $*
do variable=$(sed 's/$PATTERN/FIND/g' $file | grep FIND $file | wc-1)
echo $PATTERN $variable
exit

如有任何建议和帮助,我们将不胜感激。提前谢谢你。

使用 GNU grep 的非便携式解决方案:

file=
shift

for pattern in "$@"; do
    echo "$pattern" $(grep -o -e "$pattern" <"$file" | wc -l)
done

如果你想使用 sed 并且你的“模式”实际上是固定的字符串(不包含对 sed 有特殊意义的字符),你可以这样做:

file=
shift

for pattern in "$@"; do
    echo "$pattern" $(
        sed "s/$pattern/\n&\n/g" "$file" |\
        grep -e "$pattern" | wc -l
    )
done

您的代码有几个问题:

  • 你应该在可能发生分词的地方引用变量的使用
  • 不要使用 ALLCAPS 变量名 - 它们保留供 shell
  • 使用
  • 如果将字符串放在单引号中,则不会发生变量扩展
  • 如果你给grep一个文件,它不会读取标准输入
  • 你的 for 循环没有终止 done

这可能对你有用(GNU bash、sed 和 uniq):

f(){ local file=;
     shift;
     local args="$@";
     sed -E 's/'${args// /|}'/\n&\n/g
             s/(\n\S+)\n\S+//g
             s/\n+/\n/g
             s/.(.*)/echo ""|uniq -c/e
             s/ *(\S+) (\S+)/ /mg' $file; }

将参数分成文件和剩余参数。

在 sed 替换命令中应用参数作为交替,该命令将单词分成由两边换行符分隔的行。

删除不需要的词和不需要的换行符。

使用带有 -c 选项的 uniq 命令在 sed 替换中评估生成的文件。

重新排列输出并打印结果。

The problem is the file does not have any lines

太棒了!所以问题减少到换行。

func() {
     file=
     shift
     rgx=$(printf "%s\|" "$@" | sed 's@\|$@@');
     # put the newline between words
     sed 's/\('"$rgx"'\)/&\n/g' "$file" |
     # it's just standard here
     sort | uniq -c | 
     # filter only input - i.e. exclude fourfive
     grep -xf <(printf " *[0-9]\+ %s\n" "$@")
};
func <(echo oneonetwotwotwothreefourfive) one two three

输出:

  2 one
  1 three
  3 two