我有' file1' (比方说)100行。我想使用sed或awk将第23,71和84行(例如)打印到' file2'。这三个行号位于一个单独的文件中,列表'列表中的每个号码都在一个单独的行中。
当我使用这些命令中的任何一个时,只打印第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提供行地址吗?
答案 0 :(得分:5)
这可能适合你(GNU sed):
sed 's/.*/&p/' list | sed -nf - file1 >file2
使用list
构建sed
脚本。
答案 1 :(得分:4)
您需要在循环后执行>
以捕获所有内容。由于您在循环内使用它,文件会被覆盖。在循环内部,您需要>>
。
良好做法是在循环外部使用>
,以便在每次循环迭代期间不打开文件进行写入。
但是,如果没有awk
,您可以在for loop
内执行所有操作。
awk 'NR==FNR{a[$1]++;next}FNR in a' list file1 > file2
答案 2 :(得分:3)
您必须>>
(附加到文件)。但是你要覆盖文件。这就是为什么,你总是只在文件2中获得84行。
尝试使用,
for i in $(cat list); do sed -n "${i}p" file1 >> file2; done
答案 3 :(得分:3)
使用sed:
sed -n $(sed -e 's/^/-e /' -e 's/$/p/' list) input
给出示例输入,inner命令创建一个如下字符串:`
-e 23p
-e 71p
-e 84p
所以外部sed然后打印出给定的行
答案 4 :(得分: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