[英](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.