.bashrc
내 파일을 어떻게 공유하되 관련 부분만 공유하나요 ?
예를 들어 다음 위치에 5개의 함수를 만들었습니다 .bashrc
.
f1() {
...
}
f2() {
f1
...
}
f3() {
f2
...
}
f4() {
f1
f3
...
}
f5() {
...
}
f5()
사례 1: 동료들과 공유하고 싶어서 복사해서 f5()
붙여넣기만 하면 됩니다.
사례 2: 공유하고 싶기 때문에 복사 하여 재귀적으로 합산하고 f3()
싶습니다 .f3()
f2()
f1()
사례 3: 공유하고 싶기 때문에 AND 를 재귀적으로 f4()
복사하고 싶지만 둘 다 AND로 호출 되더라도 한 번만 복사하고 싶습니다 .f3()
f2()
f1()
f1()
f1()
f3()
f2()
지금은 수동으로 찾아서 복사하지만 오류가 발생하기 쉽습니다. 이 작업을 자동으로 수행할 수 있습니까? 저는 파이썬을 사용하지 않습니다. 모든 함수가 동일한 .bashrc
파일에 있고 내가 정의한 bash 함수라고 가정합니다.
답변1
구경하다flatten.sh. 나는 모든 별칭과 함수를 쉘 스크립트에 소스화하고 필요한 대로 평면화할 수 있도록 이 글을 썼습니다. 그래서 지금 여러분이 처한 상황과 비슷합니다.
따라서 example.lib
다음과 같은 것(또는 귀하의 것 .bashrc
):
f1() {
echo "I am f1"
}
f2() {
f1
}
f3() {
f2
}
f4() {
f1
f3
}
f5() {
:
}
example.sh
그리고 다음과 같은 스크립트:
#!/usr/bin/env -S bash -
. /path/to/example.lib
f4
너는 달려가서 flatten.sh example.sh
얻는다
#!/usr/bin/env -S bash -
f1() {
echo "I am f1"
}
f2() {
f1
}
f3() {
f2
}
f4() {
f1
f3
}
f4
답변2
다음 Perl 스크립트는 스크립트에서 함수 이름과 정의를 추출하기 위한 개념 증명 데모입니다. %funcs
각 함수 코드를 포함하는 해시(연관 배열)를 구축합니다 . 그런 다음 각 함수 정의를 검색하여 해당 함수에서 호출되는 다른 함수를 찾고 해당 정보를 해시("HoH")라는 해시에 저장합니다. 해시는 각 요소가 다른 해시입니다. 참조 man perldsc
) %contains
.
마지막으로 명령줄에 제공된 함수 이름 목록에서 시작하여 인쇄할 함수 목록( 이라는 또 다른 해시 %out
)을 작성한 다음 인쇄합니다.
이 스크립트는 개념적으로 매우 단순하고 무차별적입니다. 성능이나 단순성을 위해 코드를 최적화하려는 노력은 전혀 이루어지지 않았습니다.
참고: 이것은 완전한 쉘 코드 파서가 아닙니다(기껏해야 간단한 정규식 토큰 일치자입니다). 위의 예제 함수를 정의하는 쉘 코드, 내 자신의 ~/.bashrc 및 내장 함수 출력의 stdin에 대해서만 set
테스트 되었습니다(정의된 함수와 변수를 내부 help set
또는 외부에서도 인쇄합니다). bash 매뉴얼 페이지).
다른 쉘 코드가 이를 깨뜨릴 수도 있습니다(사실 가능성이 높습니다). 이 경우 (적어도) 토큰 추출 정규식을 수정해야 하며, 조회 함수 정의 시작 부분의 정규식도 수정해야 합니다. 인용된 문자열과 주석을 제거하는 코드가 있을 수도 있습니다. 이는 실패 가능성이 가장 높은 세 가지 지점입니다.
#!/usr/bin/perl
use strict;
use v5.10;
# primitive arg handling to separate function names from
# input files on the command line.
#
# if an argument is a filename that exists, treat it as
# an input file. If not, treat it as a function name to
# search for.
my (@args,%find) = ();
foreach (@ARGV) {
if (-e $_) {
push @args, $_; # array of input files to process
} else {
$find{$_} = 1; # hash of function name(s) to search for.
}
};
@ARGV = @args;
# Main loop, read and process the input.
# Build up a hash called %funcs with key = function name
# and val = function code.
my %funcs = ();
while(<>) {
state ($fname, $in_func, $counter);
# state variables:
# $fname - name of current function
# $in_func - are we in a function definition
# $counter - how many { and } have we seen in this function?
if (/^(?:function)?\s*([^\$(=\s]*)\s*[(]/) {
$fname = $1;
$funcs{$fname} = $_;
$in_func = 1;
# cuddled braces begin on same line as function name. uncuddled don't.
my $cuddled = () = $_ =~ (/{/g); # count of { on this line
next unless $cuddled;
$cuddled -= () = $_ =~ (/}/g); # subtract count of }s on line
$counter = $cuddled;
$in_func = $cuddled;
next;
};
if ($in_func) {
$funcs{$fname} .= $_;
my $plus = () = $_ =~ (/{/g); # count of {s on line
my $minus = () = $_ =~ (/}/g); # count of }s on line
$counter += $plus - $minus;
$in_func = ($counter > 0);
}
};
###
### Now determine which functions to print, then print them.
###
my %contains = ();
my $match = join("|", keys %funcs);
foreach my $f (keys %funcs) {
# ignore everything in quoted strings and comments by
# copying the current function to variable $function and
# stripping unwanted junk. ignore unquoted array references too.
my $function;
($function = $funcs{$f}) =~ s/"[^"]*"|'[^']*'|#.*$|\$\{[^}]}//mg;
# find tokens that *look like* calling one of our known function names
my (@tokens) = ($function =~ /(?:^|;|&{1,2}|\|{1,2}|[({])\s*($match)\b(?!=)/gm);
foreach my $t (@tokens) {
# if the current token $t is one of our known functions
# then add it to %contains{$f}
if (defined($funcs{$t})) {
$contains{$f}->{$t} = 1;
};
};
};
my %out = %find;
# Iterate over each function's name. Add the name to %out
# and %find if it is called from within a wanted function.
# Repeat until %out doesn't change.
my %old_out;
do {
%old_out = %out;
foreach my $f (keys %find) {
foreach my $t (keys %{ $contains{$f} }) {
$out{$t} = 1; # add to output hash
$find{$t} = 1; # add to list of function names to search for
};
};
} until %out == %old_out;
# print the functions listed in %out, sorted by name
# otherwise will be printed in pseudo-random order as hashes
# are un-ordered.
foreach my $f (sort keys %out) {
print $funcs{$f}, "\n";
};
예를 들어 다른 이름으로 저장하면 extract-funcs.pl
실행 파일이 chmod +x
다음과 같이 실행됩니다(함수 정의 복사본 사용 functions.txt
).
$ ./extract-funcs.pl functions.txt f1
f1() {
...
}
f1
다른 함수에 대한 호출이 포함되어 있지 않으므로 f1만 인쇄됩니다.
$ ./extract-funcs.pl functions.txt f2
f1() {
...
}
f2() {
f1
...
}
f2
f1에 대한 호출이 포함되어 있으므로 f1과 f2가 인쇄됩니다.
$ ./extract-funcs.pl functions.txt f4
f1() {
...
}
f2() {
f1
...
}
f3() {
f2
...
}
f4() {
f1
f3
...
}
f4
f1 및 f3에 대한 호출이 포함되고, f3에는 f2에 대한 호출이 포함되며, f2에는 f1에 대한 호출이 포함되므로 f1, f2, f3 및 f4가 인쇄됩니다. f1은 f4 및 f2에서 호출되더라도 한 번만 인쇄합니다.
붙여 넣기 또는 xsel -i -b
편집 메뉴에서 사용하기 위해 출력을 클립보드로 파이프할 수 있습니다 . 또는 마우스 가운데 버튼을 클릭하여 붙여넣으려면 X의 기본 선택 항목에 복사하세요. 바라보다 .CtrlVShiftInsxsel -i
man xsel