일부 스크립트 이름과 해당 경로가 텍스트 파일에 저장되어 있습니다. 텍스트 파일에는 다음과 유사한 경로가 포함되어 있습니다.
/myhome/new1/myfiles/test2.sh
/myhome/new3/myfiles/test1.sh
/myhome/new2/myfiles/test4.sh
/myhome/new/myfiles/test5.sh
이 쉘 파일은 일부 기본 스크립트에 의해 호출됩니다.
경로를 선택하고 싶습니다. 경로에 기본 경로가 있습니다(경로를 얻는 방법을 모르며 마지막 구분 기호를 보낼 수 없습니다).
sed 's/.*\///' new.txt
파일 이름을 grep하고(사용된 파일 이름을 가져오기 위해 ) 저장하고 싶습니다.쉘 유형 파일 이름스크립트는 텍스트 파일에 씁니다.
출력텍스트 파일경로, 스크립트 이름, 기본 스크립트 이름과 같아야 합니다.
/myhome/new1/myfiles/test2.sh test2 test2main.sh
/myhome/new3/myfiles/test1.sh test1 test1foo.sh
/myhome/new2/myfiles/test4.sh test4 test4bar.sh
/myhome/new/myfiles/test5.sh test5 baz5main.sh
test2main.sh
, test1foo.sh
, testo4bar.sh
...는 이러한 파일을 호출하는 주요 스크립트입니다.
답변1
이를 달성하려면 다음 스크립트를 사용할 수 있습니다. 귀하의 질문에 따르면 각 입력 파일에 대한 "마스터"파일을 정확하게 결정하는 방법이 명확하지 않습니다. 아래 스크립트에서는 해당 파일이 폴더의 유일한 다른 파일이라고 가정합니다.
#!/usr/bin/env bash
while IFS= read -r f # every line is represented by $f
do
d=$(dirname "$f") # $f's directory
b=$(basename "$f") # $f's basename
bwoe=${b%.*} # $f's basename without extension
m=$(find "$d" -mindepth 1 -maxdepth 1 -not -name "$b" | head -n 1) # get first file in the folder that is not $f
m=$(basename "$m") # basename of main file
printf "%s\\t%s\\t%s\\n" "$f" "$bwoe" "$m"
done < input.txt # input.txt contains the input scripts
예:
$ ls a b c
a:
afoo.sh a.sh
b:
bmain.sh b.sh
c:
c.sh cxx.sh
$ cat input.txt
a/a.sh
b/b.sh
c/c.sh
$ bash script.sh
a/a.sh a afoo.sh
b/b.sh b bmain.sh
c/c.sh c cxx.sh
답변2
내가 올바르게 이해했다면(주석 참조) 명령 을 한 줄로 만드는 데 도움이 될 수 있는 명령에 대한 GNU sed
플래그가 있습니다 (테스트되지 않음, 죄송합니다).e
s
sed -E 'h;s_(.*/)(.*)_grep -l \2 \1*.sh_e;x;G;s_([^/]*).sh\n_\1.sh \1 _' scriptfile
h
나중에 엉망으로 만든 후 복원할 수 있도록 해당 라인을 예약된 공간에 저장하세요.s_.*/_grep -l \2 \1*.sh_e
실제 비결은.*/
마지막 슬래시 앞의 모든 항목을 일치시켜\1
경로가 되고 줄\2
의 나머지 부분(스크립트 이름)이 되도록 하는 것입니다. 이제grep -l
스크립트 이름 앞과 경로 앞에 삽입/my/path/foo.sh
됩니다grep -l foo.sh /my/path/*.sh
. 이 플래그는 셸에서 이 모드를 실행하므로e
포함된 파일 목록으로 대체됩니다. (하나만 있으면 좋겠습니다. 그렇지 않으면 스크립트를 조정해야 합니다.)*.sh
/my/path
foo.sh
- 나머지는 간단합니다.
x
두 버퍼를 모두 변경하고 예약된 버퍼(현재 쉘의 응답 포함)를 패턴에 추가합니다. s_([^/]*).sh\n_\1.sh \1 _
정리를 수행하고 스크립트 이름을 복사하고( 없이.sh
) 줄 바꿈을 제거하면 원하는 출력을 얻을 수 있습니다.
답변3
c-shell
진정한 구원자가 될 수 있는 곳은 다음과 같습니다 .
% foreach line ( "`cat ./input.txt`" )
printf '%s\t%s\t' ${line:q} ${line:r:t:q}
printf '%smain\n' ${line:r:t:q}
end
다른 방법은 다음과 같습니다.
$ perl -F/ -pale '
my($t) = $F[-1] =~ /([^.]+)/;
$_ = join "\t", $_, $t, "${t}main" if /\S/;
' ./input.txt
$ sed -Ee '
s|([^/.]+)\.[^/.]+$|&\t\1\t\1main|;t
s|([^.]+)\.[^.]+$|&\t\1\t\1main|;t
s|([^/]+)$|&\t\1\t\1main|
' ./input.txt
결과:
/myhome/new1/myfiles/test2.sh test2 test2main
/myhome/new3/myfiles/test1.sh test1 test1main
/myhome/new2/myfiles/test4.sh test4 test4main
/myhome/new/myfiles/test5.sh test5 test5main
노트:
o We have to be verbose as we need to cover the various possible cases that may arise.
o GNU sed is needed.
답변4
sed(-r 옵션)에서 캡처 그룹 및 확장 정규식을 사용하여 파일 이름을 가져오고 최종 출력에서 원래 문자열을 스크립트로 바꿀 수 있습니다.
sed -r 's/(^.*\/)([^.]*)(.*$)/\1\2\3 \2 \2main/' test.txt
(^.*\/) -- 1st Capture, the path
([^.]*) -- 2nd Capture, the file up to the dot
(.*$) -- 3rd Capture, the file suffix