4

我有(比如说)100 行的“file1”。我想使用 sed 或 awk 将第 23、71 和 84 行(例如)打印到“file2”。这 3 个行号位于单独的文件“列表”中,每个数字位于单独的行中。

当我使用这些命令中的任何一个时,只打印第 84 行:

for i in $(cat list); do sed -n "${i}p" file1 > file2; done

for i in $(cat list); do awk 'NR==x {print}' x=$i file1 > file2; done

可以以这种方式使用 for 循环为 sed 或 awk 提供行地址吗?

4

5 回答 5

5

这可能对您有用(GNU sed):

sed 's/.*/&p/' list | sed -nf - file1 >file2

用于list构建sed脚本。

于 2013-06-11T05:56:20.070 回答
4

您需要>在循环之后执行才能捕获所有内容。由于您在循环中使用它,因此文件将被覆盖。在循环内你需要做>>.

好的做法是在循环外使用或>在循环外使用,这样在每次循环迭代期间文件都不会打开以供写入。

但是,您可以在awk没有for loop.

awk 'NR==FNR{a[$1]++;next}FNR in a' list file1 > file2
于 2013-06-11T05:29:37.320 回答
3

您必须>>(附加到文件)。但是您正在覆盖文件。这就是为什么,你总是只在 file2 中得到 84 行。

尝试使用,

for i in $(cat list); do sed -n "${i}p" file1 >> file2; done
于 2013-06-11T05:21:27.110 回答
3

使用 sed:

 sed -n $(sed -e 's/^/-e /' -e 's/$/p/' list) input

给定示例输入,内部命令创建一个像这样的字符串:`

-e 23p 
-e 71p 
-e 84p 

所以外部 sed 然后打印出给定的行

于 2013-06-11T05:31:35.083 回答
1

您可以避免在 for/while 循环中运行 sed/awk:

# store all lines numbers in a variable using pipe
lines=$(echo $(<list) | sed 's/ /|/g')

# print lines of specified line numbers and store output
awk -v lineS="^($lines)$" 'NR ~ lineS' file1 > out
于 2013-06-11T05:35:44.213 回答