Bash
在腳本(.bashrc 等)中查找重複的別名和函式
這個網站說函式比別名更快,但他正確地指出別名更容易理解——當你想要一些非常簡單的東西並且不需要考慮傳遞參數時,別名是方便和明智的。在這種情況下,我的個人資料大約有 1,000 行,既可以作為我經常使用的功能和工具的來源,也可以作為保留技術的手段,我可以參考和重用於其他任務,包括別名和裡面的功能。
但是一個問題是別名優先於函式,並且別名和函式的重新定義可能會導致問題(例如,如果我呼叫了一個函式
gg
,然後在腳本中稍後,偶然地,我呼叫了一個別名gg
- 但如果稍後重新定義函式,再次作為函式,它會覆蓋先前的定義)。配置文件載入,但我最終遇到了問題。一種解決方案可能是消除所有別名並僅使用函式(有人這樣做嗎,我很想知道,因為如果我想這樣做alias m=man
比更直覺和明智function m() { man $@; }
?),但我仍然有函式重新定義的問題在這種情況下。有沒有辦法解析腳本以回答:“對於別名或函式的每個聲明,向我顯示包含該項目的重新聲明(別名或函式)的所有行”?
嘗試這樣的事情:
$ cat find-dupes.pl #!/usr/bin/perl use strict; #use Data::Dump qw(dd); # Explanation of the regexes ($f_re and $a_re): # # Both $f_re and $a_re start with '(?:^|&&|\|\||;|&)' to anchor # the remainder of the expression to the start of the line or # immediately after a ;, &, &&, or ||. Because it begins with # '?:', this is a non-capturing sub-expression, i.e. it just # matches its pattern but doesn't return what it matches. # $f_re has two main sub-expressions. One to match 'function name ()' # (with 'function ' being optional) and the other to match # 'function name () {' (with the '()' being optional). # # Each sub-expression contains more sub-expressions, with one of # them being a capture group '([-\w.]+)' and the rest being # non-capturing (they start with '?:'). i.e. it returns the # function name as either $1 or $2, depending on which subexp # matched. my $f_re = qr/(?:^|&&|\|\||;|&)\s*(?:(?:function\s+)?([-\w.]+)\s*\(\)|function\s+([-\w.]+)\s+(?:\(\))?\s*\{)/; # $a_re matches alias definitions and returns the name of # the alias as $1. my $a_re = qr/(?:^|&&|\|\||;|&)(?:\s*alias\s+)([-\w.]+)=/; # %fa is a Hash-of-Hashes (HoH) to hold function/alias names and # the files/lines they were found on. i.e an associative array # where each element is another associative array. Search for # HoH in the perldsc man page. my %fa; # main loop, read and process the input while(<>) { s/#.*|^\s*:.*//; # delete comments s/'[^']+'/''/g; # delete everything inside ' single-quotes s/"[^"]+"/""/g; # delete everything inside " double-quotes next if /^\s*$/; # skip blank lines while(/$f_re/g) { my $match = $1 // $2; #print "found: '$match':'$&':$ARGV:$.\n"; $fa{$match}{"function $ARGV:$."}++; }; while(/$a_re/g) { #print "found: '$1':'$&':$ARGV:$.\n"; $fa{$1}{"alias $ARGV:$."}++; }; close(ARGV) if eof; }; #dd \%fa; # Iterate over the function/alias names found and print the # details of duplicates if any were found. foreach my $key (sort keys %fa) { my $p = 0; # Is this function/alias ($key) defined more than once on # different lines or in different files? if (keys %{ $fa{$key} } > 1) { $p = 1; } else { # Iterate over the keys of the second-level hash to find out # if there is more than one definition of a function/alias # ($key) in the same file on the same line ($k) foreach my $k (keys %{ $fa{$key} }) { if ($fa{$key}{$k} > 1) { $p = 1; # break out of the foreach loop, there's no need to keep # searching once we've found a dupe last; }; }; }; # print the details if there was more than one. print join("\n\t", "$key:", (keys %{$fa{$key}}) ), "\n\n" if $p; };
註釋掉的Data::Dump、
dd
行用於調試。取消註釋以更好地了解此腳本的作用及其工作原理。dd
該模組的函式輸出Data::Dump
特別有趣,因為它向您展示了%fa
HoH 的結構(和內容)。Data::Dump
perl 中不包含它,它是您需要安裝的庫模組。您沒有提到您使用的是什麼發行版,但如果您使用的是 debian/ubuntu/mint/etc,您可以使用sudo apt install libdata-dump-perl
. 其他發行版可能將其打包在稍微不同的名稱下。否則,您可以使用cpan
.範例輸出(使用包含評論中的別名以及一些虛擬函式的文件):
$ cat yorsub.aliases function foo () { echo ; } bar () { echo ; } bar () { echo ; } function baz () { echo ; } && quux () { echo ; } ; alias xyz=abc; type tmux &> /dev/null && alias t='tmux' alias cd-='cd -'; alias cd..='cd ..'; alias u1='cd ..'; alias u2='cd ../..'; alias u3='cd ../../..'; alias u4='cd ../../../../..'; alias u5='cd ../../../../../..'; alias u6='cd ../../../../../../..' alias back='cd -'; alias cd-='cd -'; alias .1="cd .."; alias .2="cd ../.."; alias .3="cd ../../.."; alias .4="cd ../../../.."; alias .5="cd ../../../../.."; alias .6='cd ../../../../../../..' function cd.. { cd .. ; } function abc () { xyx "$@" }; abc () { xyz } ; function abc { xyz }; alias abc=xyz
$ ./find-dupes.pl yorsub.aliases abc: function yorsub.aliases:8 alias yorsub.aliases:8 bar: function yorsub.aliases:3 function yorsub.aliases:2 cd-: alias yorsub.aliases:6 cd..: alias yorsub.aliases:6 function yorsub.aliases:7