shell : 如何在这个 Grep 结构中使用 UDV 而不会出现问题?
shell :How to use UDV in this Grep structure without having issues?
我有一个作业要求我在屏幕上打印比给定数字长的单词数,比方说 k ,它是从键盘上读取的。然后订购结果。
直到现在我决定以这种方式尝试:
#!bin/bash
k=0
if [ $# -eq 0 ]
then
echo "No argument supplied."
exit 1
fi
echo -n "Give the minimal lenght of the words : "
read k
for files in "$@"
do
if [ -f "$files" ]; then
echo "$(cat $files | egrep -o '[^ ]{k,}' $files | wc -w) : $files."
else
echo "Error: File $files has not been found."
fi
done | sort -n
我的问题是,每当我在 "egrep -o '[^ ]{k,}'" 部分使用 k 尝试这个程序时,它总是给出错误的答案。但是如果我用一个整数替换它,in 就会完全按照我的意愿工作。
使此代码适用于从键盘读取的 k 的正确方法是什么?这是语法,不能真正理解我应该怎么写,尝试了其他方式来喜欢“$k”、$k、((k))、k
。
欢迎任何帮助,请提示是否有人可以给我?我卡住了
尝试
echo "$(egrep -o '[^ ]{'"$k"',}' "$files" | wc -w): $files"
- 您的直接问题是使用
k
而不是 $k
。
- 要引用 Bash 中的变量,您必须在其名称前加上
$
前缀(相比之下,当 赋值 到它)。在某些情况下,为了将变量名称与后续标记分开,您必须将名称括在 {..}
中,例如 ${k}
,您也可以选择这样做以提高视觉清晰度,即使它不是严格要求的.
- 您的下一个问题是使用 单 引号来分隔
egrep
搜索正则表达式(在命令替换内),这会阻止变量引用的扩展。
- 请注意,即使您使用的是双引号字符串 总体而言,嵌入式命令替换 (
$(...)
) 也是它们自己的世界,其中通常的解析规则apply(单引号字符串是文字,而双引号字符串可能包含嵌入的变量引用、命令替换、算术扩展)。
- 但是,简单地使用 double 引号代替 - 在其中变量引用 被 扩展 - 会 可能 未修复问题在这种情况下,由于bash 3.2.57 与命令替换中的 brace expansion (
{...}
) 有关:
- 此错误在 bash 4.3.30 中不再存在(不知道何时修复),因此您可以 使用单、双- 引号字符串:
"[^ ]{$k,}"
。但是,所提供的解决方案适用于 bash 3.x 和 4.x
- 这是一个演示 bash 3.2.57 中错误的最小示例:
k=3; echo "$(egrep -co "[^ ]{$k,}" <<<$'abc\nde')"
- 这个应该return
1
,但是returns 0 2
,由于错误地将大括号扩展应用到{3,}
(产生 两个 字符串:egrep -co '[^ ]3'
和 egrep -co '[^ ]'
),即使它包含在双引号字符串中。
- 因此,答案是拼接两个单引号字符串[=91]之间的变量引用=]:
'[^ ]{'"$k"',}'
将文字 [^ ]{
与变量 $k
和文字 ,}
的值连接起来。例如,如果 $k
是 4
,则 egrep
会看到以下字符串:[^ ]{4,}
- (此外,初始的
cat $files |
是不必要的,因为该文件也作为 操作数 (非选项参数)传递,并且您应该始终双引用包含文件名的变量,因此该命令不会中断带有嵌入空格的文件名。)
- 最后,我建议将
$files
重命名为 $file
以避免混淆:在循环的每次迭代中,您只处理 单个 文件。
我有一个作业要求我在屏幕上打印比给定数字长的单词数,比方说 k ,它是从键盘上读取的。然后订购结果。 直到现在我决定以这种方式尝试:
#!bin/bash
k=0
if [ $# -eq 0 ]
then
echo "No argument supplied."
exit 1
fi
echo -n "Give the minimal lenght of the words : "
read k
for files in "$@"
do
if [ -f "$files" ]; then
echo "$(cat $files | egrep -o '[^ ]{k,}' $files | wc -w) : $files."
else
echo "Error: File $files has not been found."
fi
done | sort -n
我的问题是,每当我在 "egrep -o '[^ ]{k,}'" 部分使用 k 尝试这个程序时,它总是给出错误的答案。但是如果我用一个整数替换它,in 就会完全按照我的意愿工作。
使此代码适用于从键盘读取的 k 的正确方法是什么?这是语法,不能真正理解我应该怎么写,尝试了其他方式来喜欢“$k”、$k、((k))、k
。
欢迎任何帮助,请提示是否有人可以给我?我卡住了
尝试
echo "$(egrep -o '[^ ]{'"$k"',}' "$files" | wc -w): $files"
- 您的直接问题是使用
k
而不是$k
。- 要引用 Bash 中的变量,您必须在其名称前加上
$
前缀(相比之下,当 赋值 到它)。在某些情况下,为了将变量名称与后续标记分开,您必须将名称括在{..}
中,例如${k}
,您也可以选择这样做以提高视觉清晰度,即使它不是严格要求的.
- 要引用 Bash 中的变量,您必须在其名称前加上
- 您的下一个问题是使用 单 引号来分隔
egrep
搜索正则表达式(在命令替换内),这会阻止变量引用的扩展。- 请注意,即使您使用的是双引号字符串 总体而言,嵌入式命令替换 (
$(...)
) 也是它们自己的世界,其中通常的解析规则apply(单引号字符串是文字,而双引号字符串可能包含嵌入的变量引用、命令替换、算术扩展)。
- 请注意,即使您使用的是双引号字符串 总体而言,嵌入式命令替换 (
- 但是,简单地使用 double 引号代替 - 在其中变量引用 被 扩展 - 会 可能 未修复问题在这种情况下,由于bash 3.2.57 与命令替换中的 brace expansion (
{...}
) 有关:- 此错误在 bash 4.3.30 中不再存在(不知道何时修复),因此您可以 使用单、双- 引号字符串:
"[^ ]{$k,}"
。但是,所提供的解决方案适用于 bash 3.x 和 4.x - 这是一个演示 bash 3.2.57 中错误的最小示例:
k=3; echo "$(egrep -co "[^ ]{$k,}" <<<$'abc\nde')"
- 这个应该return
1
,但是returns0 2
,由于错误地将大括号扩展应用到{3,}
(产生 两个 字符串:egrep -co '[^ ]3'
和egrep -co '[^ ]'
),即使它包含在双引号字符串中。
- 此错误在 bash 4.3.30 中不再存在(不知道何时修复),因此您可以 使用单、双- 引号字符串:
- 因此,答案是拼接两个单引号字符串[=91]之间的变量引用=]:
'[^ ]{'"$k"',}'
将文字[^ ]{
与变量$k
和文字,}
的值连接起来。例如,如果$k
是4
,则egrep
会看到以下字符串:[^ ]{4,}
- (此外,初始的
cat $files |
是不必要的,因为该文件也作为 操作数 (非选项参数)传递,并且您应该始终双引用包含文件名的变量,因此该命令不会中断带有嵌入空格的文件名。) - 最后,我建议将
$files
重命名为$file
以避免混淆:在循环的每次迭代中,您只处理 单个 文件。