我有一个选项卡文件,我正在从中提取包含行号的列,我需要从另一个文件中提取行。我得到了行号cut -f
并将它们存储到一个变量中list
。我尝试sed
与以下内容一起使用:
$ list="2 5 7 10"
$ echo $list
2 5 7 10
$ sed -n "$list p" longText.txt
sed: -e expression #1, char 3: unknown command: `5'
$ sed -n "${list}p" longText.txt
sed: -e expression #1, char 3: unknown command: `5'
错误是什么?正确的语法是什么?
答案1
您的代码的问题是您尝试运行一个sed
类似于
2 5 7 10p
这显然对 没有意义sed
,所以它抱怨。
您的问题的一部分是使用单个字符串来保存许多不同的项目(行号)。最好使用数组来完成此操作。然后,每个数组元素(行号)需要在p
其后插入一个 ,以使其成为一个单独的sed
命令。
对于数字 2、5、7 和 10,您需要一个sed
如下所示的脚本
2p; 5p; 7p; 10p;
或者
2p;5p;7p;10p;
或者
2p
5p
7p
10p
您可以从以下数组中轻松创建这样的脚本bash
:
lines=( 2 5 7 10 )
printf '%sp\n' "${lines[@]:-"q;"}" | sed -n -f /dev/stdin longText.txt
这用于从数字列表printf
创建一个脚本,并将其提供给从标准输入读取它的脚本,并将其应用到您的文件。sed
sed
-f /dev/stdin
如果列表为空,则将printf
发出一个sed
不执行任何操作的表达式,然后终止sed
。
如果你需要要使用字符串中的数字,那么您可以将该字符串转换为有效的sed
脚本并将其应用到您的文件,如下所示:
sed 's/[[:digit:]]\{1,\}/&p;/g' <<<"$list" | sed -n -f /dev/stdin longText.txt
给定 string 2 5 7 10
,这将生成sed
脚本2p; 5p; 7p; 10p;
,然后以与上面类似的方式将其应用到您的文件。
空列表不会导致sed
输出任何内容。
答案2
只需在命令之前添加一个 echosed
即可查看哪里出错以及为什么出错。
使用编辑器的一种方法sed
是:
# assuming default IFS
## based on Kusalananda's observations
set -f ;# disable globbing
list="2 5 7 10"
for i in $list;do
echo "${i}p"
done | sed -nf - longText.txt
## or per Kusalanda method has a bug in it
## for empty list it generates wrong output
# printf '%sp\n' $list | sed -nf - lonxt.txt