[英](bash scripting) How to sort the lines that are in a position multiple of 'n' in a file?
我必须使用bash语言在ubuntu linux中编写脚本,该脚本必须在命令行中使用三个参数:首先是我必须对其行进行排序的文件的名称,其次是字母(如果要按字母顺序进行排序,则为“ a”升序或“ z”(如果我想按字母降序排序),然后将正数“ n”排在第三位。 我只需要对'n'的倍数行进行排序。 例如,如果我有一个包含100行且n = 5的文本文件,那么我只需要对5、10、15,...,100行进行排序,其余的必须保持不变。 能做到吗? 我可以找到和排序'n'的倍数的行,如下所示:
awk "NR%$n==0" archivo.txt | sort -f
但是现在我不知道如何再次将这些行写入文件中。
感谢您的关注
毫无疑问,这也可以在纯awk
完成,但是下面使用本地bash:
#!/usr/bin/env bash
input=${1:-archivo.txt} # set input to $1, or default to archivo.txt
n=${2:-5} # set n to $2, or default to 5
i=0 # initialize line counter to 0
while IFS= read -r line <&3; do # always read from input on FD 3
if (( i % n == 0 )); then # if we're on a line being sorted...
IFS= read -r line <&4 # ...overwrite $line from the awk | sort process on FD 4
fi
printf '%s\n' "$line" # write out whatever we most recently read
(( ++i )) # increment line counter
done 3<"$input" 4< <(awk -v "n=$n" 'NR%n==0' <"$input" | sort -f)
一些注意事项:
bash
(不是sh
)可确保扩展可用。 <(awk ...)
是一个进程替换-它评估为一个文件名,该文件名在读取时将提供awk
命令的输出。 4<
将文件的内容连接到文件描述符#4。 (( ))
创建算术上下文,并且是ksh和bash提供的扩展(与$(( ))
相比$(( ))
,后者由POSIX保证)。 read
详细信息(清除了IFS
并传递了-r
参数),请参阅BashFAQ#001 。 awk -v "var=$var" 'awk script using var'
可以避免在形成带有字符串连接的脚本时可能引起的错误和注入漏洞 如果您不介意将整个输入文件扔到内存中,则可以使用gawk,以便可以在打印之前对行的子集进行排序。
#!/usr/bin/env gawk -f
BEGIN {
if (!inc) inc=5 # set a default
}
NR%inc {
# This is a normal line
nosort[NR]=$0
next
}
{
# This is an increment of "inc"
tosort[NR]=$0
}
END {
# Sort the array of increments
asort(tosort)
# Step through our two arrays, picking what to print based on the modulo
n=0
for (i=1; i<NR; i++)
if (i%inc==0)
print tosort[++n]
else
print nosort[i]
}
您可能会使用类似以下的命令来运行它:
$ ./sortthing -v inc=5 inputfile
请注意,这使用了gawk函数asort()
,该函数在One True Awk中不存在。 因此,如果在* BSD或OS X上执行此操作,则可能需要安装其他工具。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.