我正在尝试从文本文件中获取特定行。
到目前为止,在网上我只看到sed之类的东西(我只能使用sh-不能使用bash或sed或类似的东西)。我只需要使用基本的shell脚本来执行此操作。
cat file | while read line
do
#do something
done
我知道如何遍历行,如上所示,但是如果我只需要获取特定行的内容怎么办
cat
可以,但sed
不可以?这是没有意义的。
我正在尝试从文本文件中获取特定行。
到目前为止,在网上我只看到sed之类的东西(我只能使用sh-不能使用bash或sed或类似的东西)。我只需要使用基本的shell脚本来执行此操作。
cat file | while read line
do
#do something
done
我知道如何遍历行,如上所示,但是如果我只需要获取特定行的内容怎么办
cat
可以,但sed
不可以?这是没有意义的。
Answers:
sed:
sed '5!d' file
awk:
awk 'NR==5' file
5!d
表示删除除5外的所有行。shell var是可能的,您需要双引号。
sed -n 5p
对于新手来说,这似乎更合乎逻辑,因为它的-n
意思是“默认情况下不输出”,p
代表“打印”,并且没有潜在的混淆性提及删除(当人们谈论文件时,删除行往往会表示不同的意思)。
-n '5p'
可以解决此问题。区别在于,5!d
您可以添加-i
将更改写回到文件中。但是,对于这个问题,-n 5p
您不得不sed -n '5p' f > f2&& mv f2 f
再次提出,我同意您的意见。
假设line
是一个变量,该变量保存您所需的行号,如果可以使用head
和tail
,那么它很简单:
head -n $line file | tail -1
如果没有,这应该起作用:
x=0
want=5
cat lines | while read line; do
x=$(( x+1 ))
if [ $x -eq "$want" ]; then
echo $line
break
fi
done
-eq
比较是针对整数,因此它需要一个行号,而不是行内容($line
)。必须通过want=5
在循环之前定义(例如)然后在-eq
上使用比较来解决此问题$want
。[
您可以使用sed -n 5p file
。
您还可以获取一个范围,例如sed -n 5,10p file
。
最佳表现方法
sed '5q;d' file
因为sed
在第五行之后停止读取任何行
Roger Dueck先生的最新实验
我安装了wcanadian-insane(6.6MB),并比较了sed -n 1p / usr / share / dict / words和sed'1q; d'/ usr / share / dict / words;第一个花费了0.043s,第二个花费了0.002s,因此使用'q'绝对是性能上的提高!
sed -n 5q
sed
在第5行之后停止读取任何行。
sed -n 1p /usr/share/dict/words
并sed '1q;d' /usr/share/dict/words
使用time
命令进行了比较;第一个花费了0.043s,第二个花费了0.002s,因此使用'q'绝对是性能上的提高!
例如,如果要获取文件的第10至20行,则可以使用以下两种方法:
head -n 20 york.txt | tail -11
要么
sed -n '10,20p' york.txt
p
在上面的命令代表打印。
做这种事情的标准方法是使用外部工具。编写shell脚本时禁止使用外部工具是荒谬的。但是,如果您确实不想使用外部工具,则可以使用以下命令打印第5行:
i=0; while read line; do test $((++i)) = 5 && echo "$line"; done < input-file
请注意,这将打印逻辑行5。也就是说,如果input-file
包含行连续,则它们将被计为单行。您可以通过添加-r
到read命令来更改此行为。(这可能是所需的行为。)
$((++i))
似乎是一种bashism;如果OP受限于使用外部工具,则我不认为他们将拥有比普通工具更多的访问权/bin/sh
$((i+=1))
可以在Dash中使用。
$(($i+1))
是我所想到的简单解决方法。
与William Pursell的答案并行的是,这是一个简单的构造,即使在原始的v7 Bourne shell中(也因此在没有Bash的地方),该构造也应工作。
i=0
while read line; do
i=`expr "$i" + 1`
case $i in 5) echo "$line"; break;; esac
done <file
break
当我们获得所需的行时,还要注意对循环外的优化。
我不特别喜欢任何答案。
这是我的方法。
# Convert the file into an array of strings
lines=(`cat "foo.txt"`)
# Print out the lines via array index
echo "${lines[0]}"
echo "${lines[1]}"
echo "${lines[5]}"