Gre*_*bet 6 grep text-processing
有时在其他表格数据中会有一些非常烦人的行,例如
column name | other column name
-------------------------------
Run Code Online (Sandbox Code Playgroud)
我通常更喜欢通过grep -ving 一个合理唯一的字符串来删除不应该存在的垃圾行,但这种方法的问题是,如果合理唯一的字符串意外出现在数据中,那将是一个严重的问题。
有没有办法限制grep -v可以删除的行数(比如 1)?对于加分,有没有办法从末尾计算行数而不诉诸于<some command> | tac | grep -v <some stuff> | tac?
您可以使用awk忽略匹配的前n行(例如,假设您只想从文件中删除第一个和第二个匹配项):
n=2
awk -v c=$n '/PATTERN/ && i++ < c {next};1' infile
Run Code Online (Sandbox Code Playgroud)
要忽略匹配的最后n行:
awk -v c=${lasttoprint} '!(/PATTERN/ && NR > c)' infile
Run Code Online (Sandbox Code Playgroud)
哪里${lasttoprint}是n文件中第 1 个到最后一个匹配项的行号。有多种方法可以获得该行号。(例如,通过sed/ 之类的工具仅打印每个匹配项的行号awk,然后tail | head提取它)...这是一种方法gnu awk:
n=2
lasttoprint=$(gawk -v c=$((n+1)) '/PATTERN/{x[NR]};
END{asorti(x,z,"@ind_num_desc");{print z[c]}}' infile)
Run Code Online (Sandbox Code Playgroud)
sed提供了一个更简单的方法:
... | sed '/some stuff/ {N; s/^.*\n//; :p; N; $q; bp}' | ...
Run Code Online (Sandbox Code Playgroud)
这样您就可以删除第一个出现的位置。
如果你想要更多:
sed '1 {h; s/.*/iiii/; x}; /some stuff/ {x; s/^i//; x; td; b; :d; d}'
Run Code Online (Sandbox Code Playgroud)
,其中 count ofi是出现次数(一次或多次,而不是零)。
sed '1 {
# Save first line in hold buffer, put `i`s to main buffer, swap buffers
h
s/^.*$/iiii/
x
}
# For regexp what we finding
/some stuff/ {
# Remove one `i` from hold buffer
x
s/i//
x
# If successful, there was `i`. Jump to `:d`, delete line
td
# If not, process next line (print others).
b
:d
d
}'
Run Code Online (Sandbox Code Playgroud)
也许,这个变体会工作得更快,因为它会读取所有其余行并一次性打印它们
sed '1 {h; s/.*/ii/; x}; /a/ {x; s/i//; x; td; :print_all; N; $q; bprint_all; :d; d}'
Run Code Online (Sandbox Code Playgroud)
您可以将此代码放入您的外壳.bashrc(或外壳的配置中,如果是其他外壳):
dtrash() {
if [ $# -eq 0 ]
then
cat
elif [ $# -eq 1 ]
then
sed "/$1/ {N; s/^.*\n//; :p; N; \$q; bp}"
else
count=""
for i in $(seq $1)
do
count="${count}i"
done
sed "1 {h; s/.*/$count/; x}; /$2/ {x; s/i//; x; td; :print_all; N; \$q; bprint_all; :d; d}"
fi
}
Run Code Online (Sandbox Code Playgroud)
并以这种方式使用它:
# Remove first occurrence
cat file | dtrash 'stuff'
# Remove four occurrences
cat file | dtrash 4 'stuff'
# Don't modify
cat file | dtrash
Run Code Online (Sandbox Code Playgroud)